找回密码
 立即注册
收起左侧

KS13-02 多线程应用中如何与主界面通信

0
回复
3760
查看
[复制链接]
累计签到:41 天
连续签到:1 天
来源: 原创 2019-9-16 10:08:56 显示全部楼层 |阅读模式

马上注册,查看详细内容!注册请先查看:注册须知

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
版权声明
---------------------------------------------------------------------------------------------------------------------
该文章原创于Qter开源社区(www.qter.org
作者: 女儿叫老白
转载请注明出处!
---------------------------------------------------------------------------------------------------------------------
引言
----------------------------------------------------------------
在使用Qt开发多线程应用时,是不能在多线程中直接操作主界面的控件的,否则将导致异常。那么在多线程中,该怎样同主界面线程通信呢?
正文
----------------------------------------------------------------
其实,这个问题在前面章节提到过,就是通过发送自定义事件给主界面,然后主界面重写自定义事件的处理函数即可。
       以前一章节的示例程序为基础,将发送数据线程改为将数据发送到主界面,不再将数据写入文件。
       首先需要定义自定义事件:
       customevent.h
  
#pragma  once
  
#include  <QEvent>
  
#include  <QString>
  
  
class  CCustomEvent : public QEvent {
  
public:
  
CCustomEvent()  Event(QEvent::Type(QEvent::User+1)){ ; }
  
~CCustomEvent() { ; }
  
    void setTeacherNumber(quint16 n) {
  
        m_nTeacherNumber = n;
  
    }
  
  
  
    quint16 getTeacherNumber() const {
  
        return m_nTeacherNumber;
  
    }
  
    void setStudentNumber(quint16 n) {
  
        m_nStudentNumber = n;
  
    }
  
  
  
    quint16 getStudentNumber() const { return  m_nStudentNumber; }
  
  
private:
  
    qint16 m_nTeacherNumber;     /// 教师人数
  
    qint16 m_nStudentNumber;     /// 学员人数
  
};
  
       然后,为CSendThread增加接口void setObject(QObjet* pObject),用来保存主界面对话框的对象指针:
  
#pragma  once
  
  
#include  <QThread>
  
QT_BEGIN_NAMESPACE
  
class  QWidget;
  
QT_END_NAMESPACE
  
  
class  CSendThread : public QThread {
  
public:
  
    CSendThread();
  
~CSendThread();
  
  
virtual void run();
  
    void setObject(QObject* pObject) {
  
        m_pObject = pObject;
  
    }
  
private:
  
    QObject * m_pObject;
  
};
  
       然后,将发送数据线程CSendThreadrun()函数修改为:
  
void  CSendThread::run()
  
{
  
    CCustomEvent* pEvent = NULL;
  
    QString str;
  
while (isRunning()) {
  
                                  sleep(1);
  
        str = QString("teacher:%1,  ").arg(CConfig::instance().getTeacherNumber());
  
        str +=  QString("student:%1\n").arg(CConfig::instance().getStudentNumber());
  
        
  
        pEvent = new CCustomEvent();
  
         pEvent->setTeacherNumber(CConfig::instance().getTeacherNumber());
  
         pEvent->setStudentNumber(CConfig::instance().getStudentNumber());
  
      
  
        QCoreApplication::postEvent(m_ pObject,  pEvent);
  
}
  
}
  
       既然主界面CDialog要接收CSendThread对象的事件,就要把自身地址传递给CSendThread,见下述代码第8行:
  
CDialog::CDialog(QWidget*  pParent) :
  
QDialog(pParent),
  
m_pRecvThread(new CRecvThread),
  
m_pSendThread(new  CSendThread) {
  
  
ui.setupUi(this);
  
  
     m_pSendThread->setObject(this);
  
connect(ui.btnStartThread, SIGNAL(clicked()),  this, SLOT(slot_startthread()));
  
}
  
       然后,为CDialog增加customEvent()接口,见下述代码第9行:
  
class  CDialog : public QDialog
  
{
  
Q_OBJECT
  
public:
  
CDialog(QWidget* pParent);
  
~CDialog();
  
  
protected:
  
    virtual void customEvent(QEvent *event);
  
  
private  slots:
  
void slot_startthread();
  
  
private:
  
    Ui::CDialogBase ui;
  
    CRecvThread* m_pRecvThread;
  
    CSendThread* m_pSendThread;
  
};
  
       编写该接口的实现代码:
  
void  CDialog::customEvent(QEvent *event) {
  
    QString str;
  
    CCustomEvent* pEvent = NULL;
  
    switch (event->type()) {
  
    case (QEvent::User + 1): {
  
        pEvent =  dynamic_cast<CCustomEvent*>(event);
  
        if (NULL != pEvent) {
  
            str = QString("teacher:%1,  ").arg(pEvent->getTeacherNumber());
  
            str +=  QString("student:%1\n").arg(pEvent->getStudentNumber());
  
            ui.textLabel->setText(str);
  
        }
  
    }
  
        break;
  
    default:
  
        break;
  
    }
  
}
  
结语
----------------------------------------------------------------
   本文又回顾了以便在多线程中通过发送自定义事件给主界面来实现操作主界面的目的。核心就是编写自定义事件类用来传递数据,然后在主界面重写void customEvent(QEvent*event)接口。
    读者可以利用这种方法实现多线程应用中在非主线程中刷新主界面的功能。


《Qt入门与提高-GUI产品开发》目录
上一节:
下一节:  

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了