1. 程式人生 > >QT 執行緒間QThread的訊號和槽

QT 執行緒間QThread的訊號和槽

問題描述:介面執行緒MainApp為主執行緒,工作執行緒MyThread為一子執行緒,從工作執行緒向主執行緒傳遞字串用於在主執行緒中顯示。

Qt的訊號與槽機制可以將任何繼承自QObject類的物件捆綁在一起,使不同物件之間能夠相互通訊。

成功的實現
工作執行緒:class MyThread:public QThread
{
  Q_OBJECT
  ...
signals:
  void MsgSignal(
const QString& tep);//用於向主執行緒傳遞字串
protected:
  void run();//run
 中的內容才是子執行緒中執行的內容!
}

void MyThread::run()
{
  Sleep(3000);//

標頭檔案:windows.h

  QString tep("mou-mou-mou");
  emit MsgSignal(tep);
  Sleep(3000);//各個Sleep的位置可放置具體執行的工作
}
主執行緒:
class MainApp:public QWidget
{
  Q_OBJECT
  ...
public:
  MainApp();
  ...
private slots:
  void OnMsgSignal(
const QString& tep2);//
接受子執行緒傳遞字串用於顯示
private:
  MyThread* m_thread;
}

MainApp::MainApp()
{
  ...
  m_thread= new MyThread();
  connect(m_thread, SIGNAL(MsgSignal(

const QString&)),
              this, SLOT(OnMsgSignal(
const QString&)));
//此處connect的第五個引數預設變成Qt::QueuedConnection
  m_thread->start();
}

void MainApp::OnMsgSignal(
const QString& tep2)
{
  //
使用子執行緒傳遞來的tep2
}

實現過程中遇到過的問題

1.connect函式的第五個引數代表訊號與槽的連線模式,執行緒間的訊號與槽不能使用Qt::DirectConnection直接連線方式,因為它要求在發訊號的執行緒內執行槽函式。而Qt::QueuedConnection佇列方式將訊號轉換成事件傳送到槽函式所線上程的訊息佇列中讓槽函式所線上程來處理,可以實現執行緒安全的執行緒間的通訊。這樣的時效性也不差,上面的實現中,會在子執行緒“run()

”函式中的第二個Sleep之前執行主執行緒的“OnMsgSignal(constQString& tep2)”。

於是在除錯的時候子執行緒的emit MsgSignal(const QString& tep);的下一步並不會立即跳轉到主執行緒的OnMsgSignal(const QString& tep2),我開始還以為訊號中途丟了沒送達呢。。而強制使用Qt::DirectConnection模式卻怎麼也擺脫不了錯誤。

2.執行緒間用“訊號與槽”傳遞引用引數的話,一定要加const,因為const文字常量存在常量區中,生命週期與程式一樣的長。這樣可以避免slot呼叫的時候引數的執行期已過而使引用無效。

我開始沒注意到需要加const,程式執行時並沒有報告錯誤,但是主執行緒毫無使用子執行緒傳遞來的字串的跡象,這讓我更加錯誤地以為子執行緒傳送的訊號丟了。

想不清楚的問題總算是解決了,前幾天憤怒抓狂的“我”們,你們可以安心休息啦Qt執行緒間的訊號與槽讓我沿著你們沒有走完的路繼續前行吧!