2010-12-02 65 views
1

我正在開發一個項目,我需要從我的系統與某些RS485串行設備進行通信。連接本身起作用,並且處於與QT GUI線程不同的線程中。慢速串行連接凍結QT GUI線程

我試圖使用信號/插槽來連接GUI線程到主要工作的串行線程,但每當外部設備需要一點響應我的GUI仍然鎖定,直到端口完成,我沒有'我無法弄清楚如何解決它。

我開始我的main.cpp的串行線是這樣的:

int main(int argc, char* argv[]) 
{ 
    QApplication app(argc, argv); 

    QFile f(":/TS-Controls.qss"); 
    if (f.open(QIODevice::ReadOnly)) { 
     app.setStyleSheet(f.readAll()); 
     f.close(); 
    } 

    for (int i = 0; i < argc; ++i) { 
     if (QString(argv[i]) == QString("-h") || 
      QString(argv[i]) == QString("--help") || 
      QString(argv[i]) == QString("-help")) { 

      qDebug() << "Usage:"; 
      qDebug() << " -embedded : show in fullscreen mode"; 
      qDebug() << " -no-embedded : show in desktop mode"; 
      qDebug() << " -white : Set every background to white for screenshots. "; 

      return 0; 
     } 
    } 
    MainWindow* mainWindow = new MainWindow(); 
    ModbusThread * thread = new ModbusThread("/dev/ttyAM1"); 
    app.connect(thread->m_conn, SIGNAL(transactionComplete(ModbusTransaction)), mainWindow->ref1, SLOT(receiveTransaction(ModbusTransaction)), Qt::DirectConnection); 
    app.connect(thread->m_conn, SIGNAL(busAvailable(bool)), mainWindow->TxQueue, SLOT(busAvailable(bool)), Qt::DirectConnection); 
    app.connect(mainWindow->TxQueue, SIGNAL(elementUnloaded(ModbusTransaction)), thread->m_conn, SLOT(loadTransaction(ModbusTransaction)), Qt::DirectConnection); 

    thread->start(); 

    mainWindow->show(); 
    return app.exec(); 
} 

正如你所看到的,線程對象的類型是ModbusThread是的QThread的子類。你也可能注意到我正在使用Qt :: DirectConnect。我嘗試使用默認的自動連接,它應該排隊,因爲串行的東西正在另一個線程中進行,但是就這個問題而言,它似乎沒有任何區別。這裏是我ModbusThread類:

#include <QThread> 
#include <modbusconn.h> 
#include <modbustransaction.h> 

#ifndef MODBUSTHREAD_H 
#define MODBUSTHREAD_H 

class ModbusThread : public QThread 
{ 
public: 
    ModbusThread(char * port); 
    ModbusConn * m_conn; 
}; 

#endif // MODBUSTHREAD_H 

#include "modbusthread.h" 

ModbusThread::ModbusThread(char * port) : QThread() 
{ 
    this->m_conn = new ModbusConn(this, port);  
} 

現在你可能想知道什麼TxQueue正在做(這是在main.cpp中的信號/槽連接上市,如果你錯過了一個對象)。這是ModbusTransaction數據類型的隊列類。我的想法是,因爲我知道實際的modbus連接可能在給定時間很忙,所以我可以使用這個隊列作爲保持緩衝區。 UI小部件基本上會在隊列中加載一個事務請求。如果modbus連接空閒,TxQueue會將它作爲信號傳遞給連接,否則它只會將其添加到隊列中。連接信號TxQueue可用於通過總線可用信號處理另一個事務。

不知何故,似乎TxQueue無法接受要添加到隊列的事務,直到連接對象完成。

我已經通過谷歌做了一些偵探,發現一個頁面,建議您在QThread的子類的構造做到這一點:

QObject::moveToThread(this); 

我給一個鏡頭,但是當我運行的我的程序無由於程序沒有與設備進行通信,因此信號/插槽似乎被觸發。

看着它,也許我應該擺脫我的Qthread子類,創建一個普通的Qthread,然後將連接對象移動到它?

我對C++和QT相當新,所以我確信有一些關於我的方法是有點關閉的。我會很感激你們可以提供的任何建議。

+0

直接連接看起來不正確,當向另一個線程發送信號時需要QueuedConnection。 moveToThread(this)不起作用,只能推,不拉,所有權:thread-> moveToThread(thread)應該是正確的。 – 2010-12-02 08:48:02

回答

0

爲了擴展線程行爲,QThread應該進行子類化。我想你應該在嘗試使用moveToThread函數之前閱讀以下文章:http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

+0

我讀了你鏈接的頁面,它似乎在說我需要使用一個普通的QThread,然後將我的ModbusConn類移動到它。但是,當我嘗試這樣做時,我實際上似乎沒有與設備進行通信。 – Smcrook 2010-12-02 16:17:26