gpt4 book ai didi

c++ - Qt - 获取数据并通过串行连接转发它们

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:23:22 35 4
gpt4 key购买 nike

我正在尝试开发一个简单的 Qt 应用程序。在我按下“开始”按钮后,应用程序应继续从设备(使用第三方库)检索数据并尽快通过串行连接转发它们。

到目前为止,我使用的(丑陋的)软件是一个控制台应用程序,它以顺序方式运行,并在主机提供数据帧后立即获取数据帧,使用以下循环:

    while(1)
{
[...]
while( MyClient.GetFrame().Result != Result::Success )
{
Sleep( 200 );
std::cout << ".";
}

[... pack and send on serial]
}

我想知道在 Qt 中实现此功能的哪种方法更方便,以保持 GUI 的响应速度,同时尽可能减少 getFrame 和串行写入函数之间的延迟。

我应该使用定时器触发的 SLOT 吗? QtConcurrent 命名空间QRunnable?每种方法的主要优点和缺点是什么?

谢谢为您的帮助!

最佳答案

由于现有库强制您轮询数据,唯一要做的就是在计时器上运行它。您可以选择执行此工作的对象是在主线程中运行,还是在工作线程中运行。无需使用 Qt Concurrent 或 QRunnable - 使用 QObject 让生活变得更简单,因为您可以轻松地向 GUI 提供反馈。

例如,对您客户端的 API 做出一些假设:

class Worker : public QObject {
Client m_client;
QSerialPort m_port;
QBasicTimer m_timer;

void processFrame() {
if (m_client.GetFrame().Result != Result::Success) return;
QByteArray frame = QByteArray::fromRawData(
m_client.GetFrame().Data, m_client.GetFrame().Size);
... process the frame
if (m_port.write(frame) != frame.size()) {
... process the error
}
}
void timerEvent(QTimerEvent * ev) {
if (ev->timerId() == m_timer.timerId()) processFrame();
}
public:
Worker(QObject * parent = 0) : QObject(parent) {}
Q_SLOT bool open(const QString & name) {
m_port.close();
m_port.setPortName(name);
if (!m_port.open(name)) return false;
if (!m_port.setBaudRate(9600)) return false;
if (!m_port.setDataBits(QSerialPort::Data8)) return false;
... other settings go here
return true;
}
Q_SLOT void start() { m_timer.start(200, this); }
Q_SLOT void stop() { m_timer.stop(); }
...
}

/// A thread that's always safe to destruct
class Thread : public QThread {
using QThread::run; // lock the default implementation
public:
Thread(QObject * parent = 0) : QThread(parent) {}
~Thread() { quit(); wait(); }
};

int main(int argc, char ** argv) {
QApplication app(argc, argv);
Worker worker;
Thread thread; // worker must be declared before thread!
if (true) {
// this code is optional, disabling it should not change things
// too much unless the client implementation blocks too much
thread.start();
worker.moveToThread(&thread);
}

QPushButton button("Start");
QObject::connect(&button, &QPushButton::clicked, [&worker]{
// Those are cross-thread calls, they can't be done directly
QMetaObject::invoke(&worker, "open", Q_ARG(QString, "COM1");
QMetaObject::invoke(&worker, "start");
});
button.show();

return app.exec(argc, argv);
}

关于c++ - Qt - 获取数据并通过串行连接转发它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22695040/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com