Qt开发-多线程与界面组件的通信(下)

一、多线程与界面组件的通信

1、子线程更改界面组件状态的本质

(1)、子线程发射信号通知主线程界面更新请求

(2)、主线程根据具体信号以及信号参数对界面组件进行修改、

2、另一种子线程通知主线程的方式 :发送自定义事件

(1)、自定义事件用于描述界面更新细节

(2)、在主窗口类重写事件处理函数event

(3)、使用postEvent函数(异步方式)发送自定义事件类对象(抛到应用程序的事件队列,然后分发出去)

A、子线程指定接收消息的对象为主窗口对象

B、在event事件处理函数中更新界面状态

自定义事件StringEvent.h

#ifndef STRINGEVENT_H
#define STRINGEVENT_H

#include 
#include 

//1.继承自QEvent
//2.提供全局唯一Type值
//3.初始化列表里初始化QEvent是用Type值
//4.在接收事件的地方重写事件处理函数

class StringEvent : public QEvent
{
    QString m_data;
public:
    //提供全局唯一的Type值
    static const QEvent::Type TYPE = static_cast(QEvent::User + 0xFF);
    explicit StringEvent(QString data = " ");

    QString data();
    ~StringEvent();
};

#endif // STRINGEVENT_H

自定义事件StringEvent.cpp

#include "StringEvent.h"
#include 

StringEvent::StringEvent(QString data) :
    QEvent(TYPE)
{
    m_data = data;
}

QString StringEvent::data()
{
    return m_data;
}

StringEvent::~StringEvent()
{
    qDebug() << "StringEvent::~StringEvent()";
}

子线程UpdataThread.h

#ifndef UPDATATHREAD_H
#define UPDATATHREAD_H

#include 
#include "StringEvent.h"

class UpdataThread : public QThread
{
    Q_OBJECT

private:
    void run();
public:
    explicit UpdataThread(QObject *parent = 0);
    
};

#endif // UPDATATHREAD_H

子线程UpdataThread.cpp

#include "UpdataThread.h"
#include 

UpdataThread::UpdataThread(QObject *parent) :
    QThread(parent)
{
}
void UpdataThread::run()
{
    QApplication::postEvent(parent(),new StringEvent("begin"));

    for(int i=0; i<10; i++)
    {
        QApplication::postEvent(parent(), new StringEvent(QString::number(i)));//事件被POST之后就会被删除

        sleep(3);
    }

    QApplication::postEvent(parent(), new StringEvent("end"));

}

Widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include 
#include "UpdataThread.h"
#include 
#include 

class Widget : public QWidget
{
    Q_OBJECT
    UpdataThread m_thread;
    QPlainTextEdit m_plainTextEdit;
public:
    Widget(QWidget *parent = 0);
    bool event(QEvent *evt);
    ~Widget();
};

#endif // WIDGET_H

Widget.cpp

#include "Widget.h"
#include "StringEvent.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    m_plainTextEdit.setParent(this);
    m_plainTextEdit.resize(100,100);
    m_plainTextEdit.move(20,20);


    m_thread.setParent(this);//这是一个小技巧,为了post事件的时候能调用parent()来指定接收者
    m_thread.start();
}

bool Widget::event(QEvent *evt)
{
    bool ret = true;

    if(evt->type() == StringEvent::TYPE)
    {
        StringEvent* se = dynamic_cast(evt);
        if(se != NULL)
        {
            m_plainTextEdit.appendPlainText(se->data());
        }
    }
    else
    {
        ret = QWidget::event(evt);
    }

    return ret;
}

Widget::~Widget()
{
    
}

main.cpp

#include 
#include "Widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    
    return a.exec();
}

二、小结

(1)、Qt可以发送自定义事件在子线程中操作界面组件

(2)、必须使用postEvent函数发送自定义事件(异步方式

(3)、发送的事件对象必须在堆上创建

(4)、子线程创建时必须附带模板对象的地址信息  

【领QT开发教程学习资料,点击下方链接莬费领取 ,先码住不迷路~】

「链接」

展开阅读全文

页面更新:2024-05-04

标签:组件   界面   重写   线程   主线   函数   信号   对象   事件   通信   方式

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top