前段时间终于把设备管理上位机完成的差不多了,用了差不多有半个月的时间了,因为对QT还不是特别的熟悉,所以中间还是摸索QT的过程。这个上位机程序用到了多线程,数据库操作,网络套接字还有一些界面操作。使用的IDE我选用的是QT CREATOR,个人觉得还是很好用的,里面集成了QT DESIGNER,QT HELP,,QT DEBUG(虽然暂时我还没用过调试器,都是使用Qdebug打印信息和QMesseageBox输出对话框来调试的),QT CREATOR编辑环境也是相当不错的,特别是自动补全功能,呵呵不用记那么多类了,还有对类和函数或对象F1可以看到帮助文档,但是有个前提就是这个类的头文件你必须声明正确,而却你的对象函数也必须写正确了,否则就看不到文档了。在编写过程也碰到了很多问题,现在就回忆一遍吧。
问题1:在多线程的编写中,我们都知道run()里面的函数对象都是在新线程中运行的,那么新线程怎么和老线程交互。
答案:编写多线程类的时候,我们把需要和主线程交互的对象放在线程类中,这样在主线程类中定义一个线程类对象,这样主线程可以访问这个线程类的对象,当然如果是直接访问,那就要这个对象是PUBLIC的了,如果不是就要通过线程类对象函数了。同时run因为是线程类的成员函数,那么他也可以访问同一个对象的成员。所以线程类对象的这个成员变量就相当于多线程的共享变量了,所以我们要互斥访问,我们可以在线程类里面定义一个锁。
问题2:窗口操作只能运行于主线程(可能原因为窗口需要QApplication的支持,而QApplication是定义在主线程中的,窗口运行在主事件循环中,而次线程的exec只是属于它的次线程循环)。当在次线程中QMessageBox();错误如下: ASSERT failure in QWidget: "Widgets must be created in the GUI thread.", file kernel/qwidget.cpp, line 1069 QObject::killTimers: timers cannot be stopped from another thread。我想要在此线程做了某个操作后就弹出个对话框进行提示,那该怎么办。、
答案:既然主线程负责窗口操作,那么我们就把这个事交给主线程来做。我是在次线程中emit一个信号,而这个信号连接的槽运行在主线程中,所以让这个槽来QMessageBox;这也说明了,如果一个功能在一个地方运行不了,那么我们可以通过信号槽机制使得它在别的地方运行,不能运行的地方抛信号,能运行的地方定义槽,信号和槽进行合适的连接,一般在构照函数中(对象的开始函数哦)。在help文档中有一句The main event loop receives events from the window system and dispatches these to the application widgets. Generally speaking, no user interaction can take place before calling exec(). 也就是说一切的窗口操作事件都是由a.exec分配的,分配到各个子窗口部件中的。
问题3:程序运行时候出现window runtime error,
答案:一般这个都是内存访问不当造成的,访问越界,访问非法数据等等,我的问题是我定义了一个QBitArray ba;然后直接ba.setbit(5,0);因为ba的一开始空间为0,所以setbit导致内存覆盖。所以我要使用的时候必须ba.setsize(size)才可以。
问题4:使用query创建表的时候表名不能以数字开头,而且不能数字和字母多次混合,例如下面的表名老是会报语法错误。错误表名: 20060801 错误原因:不能以数字开头 W2006w0801 错误原因:数字和字母不能多次混合正确表名; W20060801既字母+数字。
答案:我的表名就以字母开头吧,呵呵,当然废话,怎么搞想一切办法啊。
问题5:网络连接,连接不上主机时候,(意思就是说ping不通主机的时候)老长时间等待,又找不到QsqlSocket的阻塞机制,长时间等待会使得用户觉得程序当了
答案:,所以最后我使用了一个定时器,一连接时候就定时,4秒没有连接上的会就提示连接失败,这个时间也可以调小一点的。连接上的 话,这个定时器就什么都不做,和定时器的协调时通过一个标志变量来完成的。
问题6:操作数据库的时候查询很慢,一开始是使用QsqlQuery+QTableWidget就是建立了索引还是好慢
答案:改成QtableModel+QTableView快多了,一万条的记录秒杀。所以说还是要清楚你使用的工具啊,QT的这个工MODEL类很好很强大。
|