QT遇到的一些坑 信号槽 多线程 GBK

1、信号槽

想使用信号槽,需要继承public QWidget类

并在类中定义宏Q_OBJECT

2、GBK编码

QT的中文是UTF8编码且会自动把gbk编码转换成utf8编码

3、多线程

QT的线程是异步模型,需要把socket传到线程中,这个socket才能在子线程运行。

QT的线程模型和MFC不一样,是异步可重入模型,通过信号和槽来通信。之前很多同步的操作不太好实现。槽函数不能延时,循环sleep10ms发送数据槽函数会在最后一起发而不是单次。串口和网口只能在本线程调用,没有全局指针。

在qt中使用多线程,以前的方法创建一个自己的thread的类,继承与QThread,然后重写run方法,从而实现多线程。交新版本的qt出现了movetoThread方法实现多线程。该方法由于使用起来比较灵活,得到广发应用。

首先要创建一个继承QObject的类(myobject),然后new一个Qthread,并把创建的myobject类movetothread到创建好的子线程中,然后start子线程,这样就实现了一个子线程。主线程通过发送信号,调用myobject中的方法,从而实现在子线程中的计算。

run()

该案例中,WorkerThread 存在于实例化它的旧线程中,仅有 run() 中是在子线程中执行的。

move to Thread()

这里通过 moveToThread() 将 Object 对象移到到新线程中,如此一来整个 monitor 都将在子线程中运行并不能认为 monitor 的控制权归属于新线程!它仍然属于主线程,正如一位博主所说【在哪里创建就属于哪里】。movetoThread()的作用是将槽函数在指定的线程中调用。仅有槽函数在指定线程中调用,包括构造函数都仍然在主线程中调用!

调用 movetoThread() 时,移动对象的所有计时器将被重置。 计时器首先在当前线程中停止,然后在targetThread中重新启动(以相同的间隔),这时定时器属于子线程。若在线程之间不断移动对象可能会无限期地延迟计时器事件。

4、槽函数类型

最后一个参数 Qt::ConnectionType

Qt::AutoConnection

    默认连接类型,如果信号接收方与发送方在同一个线程,则使用 Qt::DirectConnection,否则使用 Qt::QueuedConnection;连接类型在信号 发射时 决定。

Qt::DirectConnection

    信号所连接至的槽函数将会被立即执行,并且是在发射信号的线程;倘若槽函数执行的是耗时操作、信号由 UI线程 发射,则会 阻塞 Qt的事件循环,UI会进入 无响应状态 。

Qt::QueuedConnection

    槽函数将会在接收者的线程被执行,此种连接类型下的信号倘若被多次触发、相应的槽函数会在接收者的线程里被顺次执行相应次数;当使用 QueuedConnection 时,参数类型必须是Qt基本类型,或者使用 qRegisterMetaType() 进行注册了的自定义类型。

Qt::BlockingQueuedConnection

    和 Qt::QueuedConnection 类似,区别在于发送信号的线程在槽函数执行完毕之前一直处于阻塞状态;收发双方必须不在同一线程,否则会导致 死锁 。

Qt::UniqueConnection

    执行方式与 AutoConnection 相同,不过关联是唯一的。(如果相同两个对象,相同的信号关联到相同的槽,那么第二次 connect 将失败)

上述部分引用不知道哪位博主的文章

你可能感兴趣的:(qt,qt,开发语言,c++,青少年编程,c语言)