Я работаю над проектом, в котором мне нужно общаться из моей системы с некоторыми последовательными устройствами RS485. Само соединение работает и находится в отдельном потоке, чем поток 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. Я попытался использовать 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 может быть занято в данный момент, я могу использовать эту очередь в качестве буфера хранения. В основном виджет пользовательского интерфейса будет загружать запрос транзакции в очереди. Если соединение Modbus бездействует, TxQueue передаст его как сигнал к соединению, в противном случае он просто добавит его в очередь. Соединение сообщает TxQueue, когда оно доступно для обработки другой транзакции через сигнал busAvailable.
Почему-то кажется, что TxQueue не может принимать транзакции, которые будут добавлены в очередь, до тех пор, пока объект подключения не завершится.
Я немного поработал с помощью Google и нашел страницу, которая рекомендует делать это в конструкторе вашего подкласса QThread:
QObject::moveToThread(this);
Я сделал это, но когда я запускаю свою программу, ни один из сигналов / слотов, похоже, не срабатывает, поскольку программа не связывается с устройством.
Глядя на это, возможно, мне следует избавиться от своего подкласса Qthread, создать простой Qthread, а затем переместить объект подключения к нему?
Я довольно новичок в C ++ и QT, поэтому я уверен, что в моем подходе есть что-то не совсем подходящее. Буду признателен за любые советы, которые вы, ребята, можете дать.