Qt下继承于QObject创建的线程
Qt線程
- 線程創建方法
- 示例
線程創建方法
Qt下創建線程的方法有兩種:
一種是通過繼承QThread,并重寫run()函數,在run()函數中,編寫線程所做的事情,在需要線程的文件中,創建線程對象,并通過start()函數啟動線程,運行run()函數。
另一種是繼承QObject類之后,在此類中編寫相應的信號和槽函數,在需要線程的類中,創建QThread類的指針和此類的指針,之后,通過函數movetoThread()函數實現線程的轉移,關聯信號槽后,同過QThread的指針調用start()函數開始線程。
示例
實現的功能是:在下面的界面上,程序運行起初,開始線程按鈕和停止線程按鈕都是置灰狀態,無法使用,點擊選擇文件路徑的按鈕之后,彈出一個文件選擇對話框,選擇的文件路徑顯示在右側的TextEdit控件中,此時開始線程按鈕可以使用,點擊開始線程按鈕后,開始線程的按鈕變為置灰,停止線程按鈕變為可用,PlainTextEdit文本中開始顯示所選文件的內容,并不斷的顯示其內容n遍,在這種狀態下直接關閉對話框,即沒有停止線程的情況下,關閉對話框,保證程序不奔潰,另一種,可點擊停止線程按鈕,關閉線程,PlainTextEdit中便不再繼續輸出文本,然后關閉對話框,程序正常結束。
界面如下圖所示:
界面上對象與類的對應關系,如下圖:
繼承QObject的類mythread的代碼:
mythread.h
mythread.cpp
#include "mythread.h" #include <QFile> #include <QDebug> #include <QThread>MyThread::MyThread(QObject *parent) : QObject(parent) {m_Statua = false;m_bEndThread = false; } MyThread::~MyThread() {m_Statua = false;m_bEndThread = false; }void MyThread::slotGetFileContent() {m_bEndThread = true;while(!m_Statua){QString strFileContent;strFileContent = GetFileContent();if(strFileContent.isEmpty()){return ;}emit signFileContent(strFileContent); QThread::sleep(1);//不加等待1s會出現線程讀數據太快,界面還沒來得及寫,而導致崩潰}m_bEndThread = false; }void MyThread::slotFilePath(const QString &strPath) {m_strFilePath = strPath; }void MyThread::StopThread() {m_Statua = true; }QString MyThread::GetFileContent() {QString str;QFile file(m_strFilePath);if(!file.exists()){qDebug()<<QString("%1文件不存在").arg(m_strFilePath)<<endl;return str;}if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){qDebug()<<m_strFilePath<<"文件打開失敗"<<endl;return str;}str = file.readAll();file.close();//為文件打開后記得關閉return str; }界面類dialog的代碼:
dialog.h
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" #include <QFileDialog> #include <QDebug>Dialog::Dialog(QWidget *parent) :QDialog(parent),ui(new Ui::Dialog) {ui->setupUi(this);ui->pushButtonStop->setEnabled(false);ui->pushButtonStart->setEnabled(false);myThread = new MyThread;thread = new QThread(this);connect(ui->pushButtonStart,SIGNAL(clicked()),this,SLOT(on_pushButtonStart_clicked()));connect(ui->pushButtonStop,SIGNAL(clicked()),this,SLOT(on_pushButtonStop_clicked()));connect(this,&Dialog::signFilePath,myThread,&MyThread::slotFilePath); // connect(this,&Dialog::signFilePath,&myThread,&MyThread::slotFilePath);// connect(&myThread,&MyThread::signFileContent,this,&Dialog::slotFileContent); }Dialog::~Dialog() {delete ui; }void Dialog::closeEvent(QCloseEvent *event)//防止線程正在運行時,關閉進程導致的崩潰 {if(thread->isRunning()){myThread->StopThread();thread->quit();thread->wait();} // if(thread.isRunning()) // { // myThread.StopThread();// while(myThread.m_bEndThread) // { // qDebug()<<"-->closeEvent"; // QThread::sleep(1); // } // qDebug()<<"-->closeEvent thread end"; // thread.quit(); // thread.wait(); // }event->accept(); }void Dialog::slotFileContent(const QString &str) {ui->plainTextEdit->appendPlainText(str); }void Dialog::on_pushButton_clicked() {QString strCurPath = QDir::currentPath();QString strFileter = QString("源文件(*.h *.cpp);;文本文件(*.txt);;所有文件(*.*)");//QString strFilePath = QFileDialog::getOpenFileName(this,tr("選擇文件"),strCurPath,strFileter);if(strFilePath.isEmpty()){return ;}ui->textEdit->setText(strFilePath);emit signFilePath(strFilePath);ui->pushButton->setEnabled(false);ui->pushButtonStart->setEnabled(true); }void Dialog::on_pushButtonStart_clicked() {ui->pushButtonStop->setEnabled(true);ui->pushButtonStart->setEnabled(false); // myThread = new MyThread; // thread = new QThread(this);myThread->moveToThread(thread);//定義為指針就沒有問題 // myThread.moveToThread(&thread);connect(thread,&QThread::started,myThread,&MyThread::slotGetFileContent);connect(thread,&QThread::finished,myThread,&QObject::deleteLater);connect(myThread,&MyThread::signFileContent,this,&Dialog::slotFileContent);thread->start(); // connect(&thread,&QThread::started,&myThread,&MyThread::slotGetFileContent); // connect(&thread,&QThread::finished,&myThread,&QObject::deleteLater); // connect(&myThread,&MyThread::signFileContent,this,&Dialog::slotFileContent); // thread.start(); }void Dialog::on_pushButtonStop_clicked() {if(thread->isRunning()){myThread->StopThread();thread->quit();//定義為變量會出現停止線程的時候沒有停止,且加上quit()函數后會卡死,直接關閉對話框會崩潰,提示線程正在運行被關閉了thread->wait();ui->pushButton->setEnabled(true);ui->pushButtonStop->setEnabled(false);} // if(thread.isRunning()) // { // myThread.StopThread(); // while(myThread.m_bEndThread) // { // qDebug()<<"-->clos button"; // QThread::sleep(1); // } // qDebug()<<"-->clos button thread end"; // thread.exit();//定義為變量會出現停止線程的時候沒有停止,且加上quit()函數后會卡死,直接關閉對話框會崩潰,提示線程正在運行被關閉了 // //thread.wait(); // ui->pushButton->setEnabled(true); // ui->pushButtonStop->setEnabled(false); // } }主函數main函數的代碼沒變:
#include "dialog.h" #include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Dialog w;w.show();return a.exec(); }初次嘗試,第一此定義的QThread對象和繼承于QObject的類的對象,沒有用指針,但是不知為啥,總是會程序奔潰,最后采用了指針,程序可以正常運行。求一份定義變量的情況下,此程序可以正常運行的指導,望各位同仁不吝賜教。
總結
以上是生活随笔為你收集整理的Qt下继承于QObject创建的线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 监听桌面鼠标事件,鼠标事件的监
- 下一篇: 修改html自带组件样式,能否直接在组件