我正在開發一個項目,我需要從我的系統與某些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相當新,所以我確信有一些關於我的方法是有點關閉的。我會很感激你們可以提供的任何建議。
直接連接看起來不正確,當向另一個線程發送信號時需要QueuedConnection。 moveToThread(this)不起作用,只能推,不拉,所有權:thread-> moveToThread(thread)應該是正確的。 – 2010-12-02 08:48:02