Inheriting QSerialPort
Inheriting QSerialPort
本文关键字:QSerialPort Inheriting 更新时间:2023-10-16
也许是一个相当愚蠢和新手的问题,但我一直在努力保持我的QSerialPort serial;
在我正在制作的整个应用程序中使用。(呃,这解释起来令人沮丧)
为了更清楚,我已经在我的MainWindow.cpp
中建立了上述QSerialPort serial;
,但是当我过渡到另一种具有不同类的形式(例如operations.cpp
)时,我不确定如何保留和使用我的serial.*
函数。我的主窗口.cpp表单只是一个连接设置表单,允许您选择要设置的端口、波特率、数据位、奇偶校验等,一旦我按下"打开连接"按钮,我就会隐藏表单(this->hide();
)并出现操作.cpp表单。
有什么线索吗?
---
我曾尝试对类使用父子关系,但是,它只启动了一个新的QSerialPort serial;
并且连接丢失了。
您应该分解出一个执行通信的单独QObject
类,并将其他类连接到该类。
一个设计良好的系统永远不会拥有UI类并直接使用串行端口。例如,请参阅此答案,了解如何分离通信和UI。
让我们看看你可以对代码执行哪些转换。目前,您可能有类似于以下内容的内容:
// https://github.com/KubaO/stackoverflown/tree/master/questions/serial-owner-41715726
#include <QtWidgets>
#include <QtSerialPort>
class Operations1 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_send{"Send"};
QPointer<QSerialPort> m_serial;
public:
Operations1() {
m_layout.addWidget(&m_send);
connect(&m_send, &QPushButton::clicked, this, &Operations1::sendRequest);
}
void sendRequest() {
QByteArray request;
QDataStream ds(&request, QIODevice::WriteOnly);
ds << qint32(44);
m_serial->write(request);
}
void setSerial(QSerialPort * port) {
m_serial = port;
}
};
class MainWindow1 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_open{"Open"};
QSerialPort m_serial;
QScopedPointer<Operations1> m_operations;
Operations1 * operations() {
if (!m_operations)
m_operations.reset(new Operations1);
return m_operations.data();
}
public:
MainWindow1() {
m_layout.addWidget(&m_open);
connect(&m_open, &QPushButton::clicked, this, &MainWindow1::open);
}
void open() {
m_serial.setBaudRate(38400);
m_serial.setPortName("/dev/tty.usbserial-PX9A3C3B");
if (!m_serial.open(QIODevice::ReadWrite))
return;
operations()->show();
operations()->setSerial(&m_serial);
}
};
int main1(int argc, char ** argv) {
QApplication app{argc, argv};
MainWindow1 ui;
ui.show();
return app.exec();
}
使用串行端口的功能分布在 UI 类中,将它们与端口紧密耦合。让我们通过分解端口操作来解决这个问题:
class Controller2 : public QObject {
Q_OBJECT
QSerialPort m_port;
public:
Controller2(QObject * parent = nullptr) : QObject{parent} {
connect(&m_port, &QIODevice::bytesWritten, this, [this]{
if (m_port.bytesToWrite() == 0)
emit allDataSent();
});
}
Q_SLOT void open() {
m_port.setBaudRate(38400);
m_port.setPortName("/dev/tty.usbserial-PX9A3C3B");
if (!m_port.open(QIODevice::ReadWrite))
return;
emit opened();
}
Q_SIGNAL void opened();
Q_SLOT void sendRequest() {
QByteArray request;
QDataStream ds(&request, QIODevice::WriteOnly);
ds << qint32(44);
m_port.write(request);
}
Q_SIGNAL void allDataSent();
};
class Operations2 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_send{"Send"};
QPointer<Controller2> m_ctl;
public:
Operations2(Controller2 * ctl, QWidget * parent = nullptr) :
QWidget{parent},
m_ctl{ctl}
{
m_layout.addWidget(&m_send);
connect(&m_send, &QPushButton::clicked, m_ctl, &Controller2::sendRequest);
}
};
class MainWindow2 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_open{"Open"};
QPointer<Controller2> m_ctl;
QScopedPointer<Operations2> m_operations;
Operations2 * operations() {
if (!m_operations)
m_operations.reset(new Operations2{m_ctl});
return m_operations.data();
}
public:
MainWindow2(Controller2 * ctl, QWidget * parent = nullptr) :
QWidget{parent},
m_ctl{ctl}
{
m_layout.addWidget(&m_open);
connect(&m_open, &QPushButton::clicked, m_ctl, &Controller2::open);
connect(m_ctl, &Controller2::opened, this, [this]{
operations()->show();
});
}
};
int main2(int argc, char ** argv) {
QApplication app{argc, argv};
Controller2 controller;
MainWindow2 ui(&controller);
ui.show();
return app.exec();
}
最后,如果您厌倦了显式传递控制器,我们可以实现一种类似于 QCoreApplication::instance
的方法来访问唯一的控制器实例:
class Controller3 : public QObject {
Q_OBJECT
QSerialPort m_port;
static Controller3 * instance(bool assign, Controller3 * newInstance = nullptr) {
static Controller3 * instance;
if (assign)
instance = newInstance;
return instance;
}
public:
Controller3(QObject * parent = nullptr) : QObject{parent} {
connect(&m_port, &QIODevice::bytesWritten, this, [this]{
if (m_port.bytesToWrite() == 0)
emit allDataSent();
});
instance(true, this);
}
~Controller3() {
instance(true);
}
Q_SLOT void open() {
m_port.setBaudRate(38400);
m_port.setPortName("/dev/tty.usbserial-PX9A3C3B");
if (!m_port.open(QIODevice::ReadWrite))
return;
emit opened();
}
Q_SIGNAL void opened();
Q_SLOT void sendRequest() {
QByteArray request;
QDataStream ds(&request, QIODevice::WriteOnly);
ds << qint32(44);
m_port.write(request);
}
Q_SIGNAL void allDataSent();
static Controller3 * instance() {
return instance(false);
}
};
class Operations3 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_send{"Send"};
public:
Operations3(QWidget * parent = nullptr) : QWidget{parent}
{
m_layout.addWidget(&m_send);
connect(&m_send, &QPushButton::clicked, Controller3::instance(), &Controller3::sendRequest);
}
};
class MainWindow3 : public QWidget {
Q_OBJECT
QVBoxLayout m_layout{this};
QPushButton m_open{"Open"};
QScopedPointer<Operations3> m_operations;
Operations3 * operations() {
if (!m_operations)
m_operations.reset(new Operations3);
return m_operations.data();
}
public:
MainWindow3(QWidget * parent = nullptr) : QWidget{parent}
{
m_layout.addWidget(&m_open);
connect(&m_open, &QPushButton::clicked, Controller3::instance(), &Controller3::open);
connect(Controller3::instance(), &Controller3::opened, this, [this]{
operations()->show();
});
}
};
int main3(int argc, char ** argv) {
QApplication app{argc, argv};
Controller3 controller;
MainWindow3 ui;
ui.show();
return app.exec();
}
相关文章:
- QSerialPort 在应用程序启动之前正在使用中
- QSerialPort readyRead() 信号无法正常工作
- QSerialPort 有可用字节,但无法读取
- QSerialPort连续读取累积延迟
- 与QSerialPort配合使用的串行端口仿真
- QSerialPort 手动 RTS 开/关未同步呼叫
- 无法使用 QSerialPort 读取任何内容
- Inheriting QSerialPort
- 来自 QSerialPort 的 readAll() 不包括上次发送的响应
- 使用QT Creator对QSerialPort中的错误进行多重定义
- 确保QSerialPort.close在程序执行完成之前完成
- QFileDialog::getExistingDirectory处于活动状态时,QSerialPort停止响应
- QSerialPort::readLine 在 MS Windows 上无法按预期工作
- QSerialPort 无法在 Ubuntu 上打开"/dev/ttyUSB0"
- QSerialPort许多线路的正确发送
- QSerialPort可以读取超过512字节的数据
- 为什么我可以在Qt 5.5.1中使用QSerialPort*作为临时变量,但不能用作类的成员?
- QSerialPort readyread() SIGNAL
- Qt 5.1 使用 QSerialPort 的串行通信
- 无法写入以使用 socat 打开 QSerialPort