2010-12-02 24 views
1

私はシステムからいくつかのRS485シリアルデバイスに通信する必要があるプロジェクトに取り組んでいます。接続自体は動作し、QT GUIスレッドとは別のスレッドにあります。ゆっくりとシリアル接続がQT 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(); 
} 

は、スレッドオブジェクトは、QThreadのサブクラスであるタイプModbusThreadです。また、私はQt :: DirectConnectを使用していることがわかります。私はシリアルのものが別のスレッドで行われているので、キューに入れられるべきデフォルトのAutoConnectを使ってみましたが、この問題の面で違いを生み出すようには見えません。ここに私の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はそれを信号として接続に渡します。それ以外の場合は、それを単にキューに追加します。 busAvailable信号を介して別のトランザクションを処理するために利用可能な場合、接続信号TxQueue。

何とかTxQueueが接続オブジェクトが終了するまで、キューに追加されるトランザクションを受け入れることができないようです。

私はグーグル経由でいくつかのsleuthingを行って、あなたのQThreadのサブクラスのコンストラクタでこれを行うことをお勧めページを発見した:

QObject::moveToThread(this); 

私はそのショットを与えたが、私は私のプログラムのどれを実行していないときプログラムがデバイスと通信していないため、信号/スロットがトリガされているように見えます。

私のQthreadサブクラスを取り除き、プレーンなQthreadを作成して接続オブジェクトをそれに移動する必要がありますか?

私はC++とQTでかなり新しくなっています。だから私のアプローチがちょっと離れていると確信しています。私はあなたが提供できるアドバイスに感謝します。

+0

直接接続が間違っていると、信号を別のスレッドに送信するときにQueuedConnectionが必要になります。 moveToThread(この)は動作しません、1つだけをプル、所有権をプルすることはできません:スレッド - > moveToThread(スレッド)が正しいはずです。 –

答えて

0

QThreadはスレッド動作を拡張するためにのみサブクラス化する必要があります。 http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/

+0

リンク先のページを読みました。通常のQThreadを使用してModbusConnクラスを移動する必要があるようです。しかし、私がこれをしようとすると、実際にはデバイスと通信しているようには見えません。 – Smcrook

+0

私がやっていることはこれです: – Smcrook

+0

QThread * commThread = new QThread(); ModbusConn * conn =新しいModbusConn(0、 "/ dev/ttyAM1"); commThread-> start(); conn-> moveToThread(commThread); app.connect(conn、SIGNAL(transactionComplete(ModbusTransaction))、mainWindow-> ref1、SLOT(receiveTransaction(ModbusTransaction))、Qt :: QueuedConnection); (ブール))、Qt :: QueuedConnection);そして、Qt :: QueuedConnection()を使用します。app.connect(mainWindow-> TxQueue、SIGNAL(elementUnloaded(ModbusTransaction))、conn、SLOT(executeTransaction(ModbusTransaction))、Qt :: QueuedConnection); – Smcrook

関連する問題