zoukankan      html  css  js  c++  java
  • 第八十五课、多线程与界面组件的通信(下)------------------狄泰软件学院

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

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

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

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

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

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

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

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

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

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

    #ifndef STRINGEVENT_H
    #define STRINGEVENT_H
    
    #include <QEvent>
    #include <QString>
    
    //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::Type>(QEvent::User + 0xFF);
        explicit StringEvent(QString data = " ");
    
        QString data();
        ~StringEvent();
    };
    
    #endif // STRINGEVENT_H
    自定义事件StringEvent.h
    #include "StringEvent.h"
    #include <QDebug>
    
    StringEvent::StringEvent(QString data) :
        QEvent(TYPE)
    {
        m_data = data;
    }
    
    QString StringEvent::data()
    {
        return m_data;
    }
    
    StringEvent::~StringEvent()
    {
        qDebug() << "StringEvent::~StringEvent()";
    }
    自定义事件StringEvent.cpp
    #ifndef UPDATATHREAD_H
    #define UPDATATHREAD_H
    
    #include <QThread>
    #include "StringEvent.h"
    
    class UpdataThread : public QThread
    {
        Q_OBJECT
    
    private:
        void run();
    public:
        explicit UpdataThread(QObject *parent = 0);
        
    };
    
    #endif // UPDATATHREAD_H
    子线程UpdataThread.h
    #include "UpdataThread.h"
    #include <QApplication>
    
    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"));
    
    }
    子线程UpdataThread.cpp
    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <QtGui/QWidget>
    #include "UpdataThread.h"
    #include <QEvent>
    #include <QPlainTextEdit>
    
    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.h
    #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<StringEvent*>(evt);
            if(se != NULL)
            {
                m_plainTextEdit.appendPlainText(se->data());
            }
        }
        else
        {
            ret = QWidget::event(evt);
        }
    
        return ret;
    }
    
    Widget::~Widget()
    {
        
    }
    Widget.cpp
    #include <QtGui/QApplication>
    #include "Widget.h"
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        Widget w;
        w.show();
        
        return a.exec();
    }
    main.cpp

    二、小结

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

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

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

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

  • 相关阅读:
    com.android.ide.common.process.PrecessException:org.gradle.process....finished with non-zero exit value 1
    android 学习笔记(1)
    C#遍历指定文件夹中的所有文件(转)
    让TextView里面的文字逐个显示的动画效果实现(1)
    This Handler class should be static or leaks might occur(null) 解决办法 (转)
    Android开发 旋转屏幕导致Activity重建解决方法(转)
    SQLite 数据库
    【Android】error opening trace file: No such file or directory (2)
    WPF中的RichTextBox
    android中的 Toast 和 AlertDialog
  • 原文地址:https://www.cnblogs.com/gui-lin/p/6504289.html
Copyright © 2011-2022 走看看