小玩具——温度采集项目(四)

来源:互联网 发布:免费外贸客户搜索软件 编辑:程序博客网 时间:2024/04/29 10:05


login_dialog是登陆的界面和一些操作的编写, dialog是主界面人机交互的时候对话框的编写,connection是通信的编写,sql_connect当然是有关数据库的操作了, widget是主界面的编写,是总体的调控管理者。而qcustomplot是一个画图的一个函数库,我就是用的这个来画折线图的,不过在v2.0版本的时候,我用的是Qt自带的画图函数来写的,得到点击一下界面它才能更新最新的最状态,而且没有qcustomplot那么好看,不过权当做练习。

我写的时候思路,当然是先写核心代码,通信部分,其实它的构成挺清晰的,分为通信部分,画图部分,就两个主要的,其他都不是必要的,登陆界面是为了熟练一下刚刚学的dialog,还有练习一下数据库的编写,为后面把数据存储进数据库做抛砖引玉。

不过我讲的时候,不按我写的先后顺序,按模块的逻辑操作顺序进行说明。

1.登陆界面,logindialog,你会发现,会有一个logindialog_ui.h这个头文件,其实,这个也是我的一个尝试练习。在使用的desinger设计师界面,可以自己脱移控件进行生成和布局界面,这个非常方便,只要在外面通过ui找到其名字的就可以操作该控件了,非常方便,但是也想明白它的原理,也想只通过c++代码进行操作来达到相同的效果。我之前有在Qt专题中说过,ui界面是通过xml来生成hpp文件,那么理论上就可以直接写c++代码来对其操作。但是,有一个细节,就是

namespace Ui{class login_dialog;}
namespace Ui {class Widget;}
所有引用了那个_ui.h的界面都有这个,这个应该是c++就有的作用域的语法,查着好像叫做pImpl的手法,作用是为了减少编译的区域,因为designer毕竟有频繁的更动,所以为了减少编译的区域范围,而使用的这个c++的编程方法。而我对编译还不太了解,也还没深入了解,先记着它的使用方法和作用的,等真正知道了编译的过程之后应该会豁然开朗吧。作用:为了减少编译的作用区域,因为修改代码时会对更动的编译器所认为有更动的区域重新编译,而pImpl就时为此而来。使用方法:前置声明一个类,只定义类的指针,指向我们所需的类,这样,可以减少耦合,使编译只涉及接口,而不涉及定义。我是看了这一篇文章的。http://blog.csdn.net/qq419036154/article/details/6291296

还是不怎么理解,mark一下。

其二,信号与槽的问题,其实这个是我在写dialog的时候就出现了,而不是写logindialog,那个问题困扰了我一天,最后才有点似懂非懂的。总结一下:

槽函数:
槽函数由5种重载方式,先不一一列出。
大致分为,调用本地信号和槽函数,调用自定义的信号和槽函数。不能混用。
QObject::connect(btn_cel, SIGNAL(clicked()), dia, SLOT(reject()));
QObject::connect(btn_ok,&QPushButton::clicked,this,&dialog::get_IP);
调用默认要用SIGNAL()  SLOT()函数,要根据前面的发出源和接收源,确定格式,我这里的dia是一个QDialog的实例,所以我可以使用QDialog的私有槽函数,如果写成this,这个是在我自己定义的一个类中写的,则只能调用,该类中的槽函数,尽管此类已经继承QDialog,但是这是私有啊!!!!!不会继承到我定义的类中,自定义要按照下面来写,还是要注意源的问题,再者就是变量是指针的话不用加&,不是要加&。

还有带参数的信号与槽函数的问题,使用带参数的,必须是可见的,也就是是该信号和该槽的输入参数,而且信号的参数必须比槽的多,不会比槽的少,触发信号时,会连接到槽函数,参数也会一起发送到槽函数。而自定义的信号怎么写呢?信号不没有具体的实现,只有声明,那么我们怎么触发该信号呢?使用emit发送信号,在你想触发信号信号的地方,emit signal();这样就会发送信号,触发槽函数。

其三,就是

int main(int argc, char *argv[]){    QApplication a(argc, argv);    if(!create_sqlconnection())return 0;        //创建数据库    Widget w;                       //主界面实例    login_dialog log_dia;           //登陆界面实例    if(log_dia.exec() == QDialog::Accepted)//是否登陆成功    {        w.show();                   //成功则显示主界面        return a.exec();            //消息循环    }    else return 0;}
正如备注那样,我创建了log_dia的对象实例,log_dia.exec()进入消息循环,等待退出,
QDialog::accept();
这一句是,我完成了登陆成功后的一个操作语句,就是返回Accepted给exec告诉它我已经登陆成功了,然后就退出登陆界面,w.show()//显示主界面,a.exec()消息循环。需要注意的是close()是Qwidget的函数,QDialog继承了QWidget,但是我使用close()是关闭不了处于exec()状态的dialog的,只能关闭show()下的,而且处于show状态下的,才有模态和非模态这种说法,而且,窗口是显示了,而程序是不会阻塞,会一直往下运行,也就是

w.show();                            //不会停留在这里

qDebug()<<1;                    //显示之后就运行下一跳语句,显示1在调试部分

exec()的模态是活动级别的,或者是窗口级别的,没有非模态,要么阻塞整个程序,要么阻塞窗口,也就是,它会停留在a.exec();等待关闭,而不会一直往下执行。回到原来的问题,那么我应该怎么关闭处于exec()下的窗口呢?!Qdialog可以使用它自带的accept(),reject(),done(),open()它们回把窗口关闭,并且把相应的值传给exec(),其实exec是个槽函数,所以它的传递应该就是通过信号-槽机制还传递的了。所以,我们在使用的时候,只需要判断它的返回值是什么就知道是因为什么操作而关闭这个窗口的了,而做出相应的动作。


原创粉丝点击