Qt 基于QObject建立class

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt的事件过滤器 Qt事件模型一个真正强大的特色是一个QObject 的实例能够管理另一个QObject 实例的事件。 让我们试着设想已经有了一个CustomerInfoDialog的小部件。CustomerInfoDialog 包含一系列QLineEdit. 现在,我们想用空格键来代替Tab,使焦点在这些QLineEdit间切换。 一个解决的方法是子类化QLineEdit,重新实现keyPressEvent(),并在keyPressEvent()里调用focusNextChild()。像下面这样: void MyLineEdit::keyPressEvent(QKeyEvent *event) { if (event->key() == Qt::Key_Space) { focusNextChild(); } else { QLineEdit::keyPressEvent(event); } } 但这有一个缺点。如果CustomerInfoDialog里有很多不同的控件(比如QComboBox,QEdit,QSpinBox),我们就必须子类化这么多控件。这是一个烦琐的任务。 一个更好的解决办法是: 让CustomerInfoDialog去管理他的子部件的按键事件,实现要求的行为。我们可以使用事件过滤器。 一个事件过滤器的安装需要下面2个步骤: 1, 调用installEventFilter()注册需要管理的对象。 2,在eventFilter() 里处理需要管理的对象的事件。 一般,推荐在CustomerInfoDialog的构造函数中注册被管理的对象。像下面这样: CustomerInfoDialog::CustomerInfoDialog(QWidget *parent) : QDialog(parent){ ... firstNameEdit->installEventFilter(this); lastNameEdit->installEventFilter(this); cityEdit->installEventFilter(this); phoneNumberEdit->installEventFilter(this); } 一旦,事件管理器被注册,发送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit的事件将首先发送到eventFilter()。 下面是一个 eventFilter()函数的实现: bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event) { if (target == firstNameEdit || target == lastNameEdit || target == cityEdit || target == phoneNumberEdit) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Space) { focusNextChild(); return true; } } } return QDialog::eventFilter(target, event); } 在上面的函数中,我们首先检查目标部件是否是 firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit。接着,我们判断事件是否是按键事件。如果事件是按键事件,我们把事件转换为QKeyEvent。接着,我们判断是否按下了空格键,如果是,我们调用focusNextChild(),把焦点传递给下一个控件。然后,返回,true通知Qt,我们已经处理了该事件。 如果返回false的话,Qt继续将该事件发送给目标控件,结果是一个空格被插入到QLineEdit中。 如果目标控件不是 QLineEdit,或者按键不是空格键,我们将把事件传递给基类的eventFilter()函数。 Qt提供5个级别
Qt Creator 多线程读取文件到程序显示 利用QT Creator多任务读取一个文档到程序里 为了防止直接读取文件里的内容太大而发生卡顿,于是多线程读取将更高效的解决这个问题。 效果图如下: 其中pro文件无需改动,默认就好,头文件h里面的内容为 #ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MyObj; class MyObj : public QObject { Q_OBJECT public: MyObj(); //新的线程 signals: void toLine(QString line); private slots: void doWork(); }; class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private slots: void appendText(QString); //定义一个槽 private: Ui::MainWindow *ui; QThread *t; MyObj *obj; }; #endif // MAINWINDOW_H 而MAIN主文件的内容为了防止中文乱码做了如下修改: #include "mainwindow.h" #include #include int main(int argc, char *argv[]) { QApplication a(argc, argv); //设置中文字体 防止乱码 a.setFont(QFont("Microsoft Yahei", 9)); //设置中文编码 #if (QT_VERSION <= QT_VERSION_CHECK(5,0,0)) #if _MSC_VER QTextCodec *codec = QTextCodec::codecForName("GBK"); #else QTextCodec *codec = QTextCodec::codecForName("UTF-8"); #endif QTextCodec::setCodecForLocale(codec); QTextCodec::setCodecForCStrings(codec); QTextCodec::setCodecForTr(codec); #else QTextCodec *codec = QTextCodec::codecForName("UTF-8"); QTextCodec::setCodecForLocale(codec); #endif MainWindow w; w.show(); return a.exec(); } 接下来重点来了,源文件CPP里为 #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include #include #include MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); t = new QThread(); //QThread obj = new MyObj(); obj->moveToThread(t); qDebug()<<"main thread:"<<QThread::currentThread(); connect(t,SIGNAL(started()), obj, SLOT(doWork())); connect(obj,SIGNAL
好的,我可以为您介绍一下如何基于QObject自定义类QModbusTcpClient类和QModbusDataUnit类。首先,您需要了解Qt的基本概念和语法,熟悉Qt的开发环境和工具。 QModbusTcpClient类是一个用于Modbus TCP通信的客户端类,它继承自QTcpSocket类,可以通过TCP/IP网络与Modbus设备通信。要基于QObject自定义QModbusTcpClient类,您可以按照以下步骤进行操作: 1.创建一个新的类并继承自QObject类。 ```cpp class MyModbusTcpClient : public QObject { Q_OBJECT public: explicit MyModbusTcpClient(QObject *parent = nullptr); ~MyModbusTcpClient(); Q_INVOKABLE bool connectDevice(); Q_INVOKABLE void disconnectDevice(); signals: void connected(); void disconnected(); void errorOccurred(const QString &errorString); private: QModbusTcpClient *m_modbusClient; }; ``` 2.在类的构造函数中创建QModbusTcpClient对象,并将其设置为父对象。 ```cpp MyModbusTcpClient::MyModbusTcpClient(QObject *parent) : QObject(parent) { m_modbusClient = new QModbusTcpClient(this); } ``` 3.添加自定义的connectDevice()和disconnectDevice()方法,用于连接和断开Modbus设备。 ```cpp bool MyModbusTcpClient::connectDevice() { if (m_modbusClient->state() != QModbusDevice::ConnectedState) { if (!m_modbusClient->connectDevice()) { emit errorOccurred(m_modbusClient->errorString()); return false; } } emit connected(); return true; } void MyModbusTcpClient::disconnectDevice() { if (m_modbusClient->state() == QModbusDevice::ConnectedState) { m_modbusClient->disconnectDevice(); emit disconnected(); } } ``` 4.在自定义的connectDevice()方法中,您可以设置Modbus设备的IP地址和端口号,以及其他一些参数。 ```cpp bool MyModbusTcpClient::connectDevice() { if (m_modbusClient->state() != QModbusDevice::ConnectedState) { // 设置Modbus设备的IP地址和端口号 m_modbusClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502); m_modbusClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "192.168.1.1"); // 设置其他参数 m_modbusClient->setNumberOfRetries(3); m_modbusClient->setTimeout(1000); if (!m_modbusClient->connectDevice()) { emit errorOccurred(m_modbusClient->errorString()); return false; } } emit connected(); return true; } ``` 5.使用自定义的QModbusTcpClient类进行Modbus通信。 ```cpp MyModbusTcpClient modbusClient; if (!modbusClient.connectDevice()) { qWarning() << "Failed to connect to Modbus device"; return; } QModbusDataUnit readUnit(QModbusDataUnit::InputRegisters, 0, 10); if (auto *reply = modbusClient.m_modbusClient->sendReadRequest(readUnit, 1)) { if (!reply->isFinished()) { QEventLoop loop; QObject::connect(reply, &QModbusReply::finished, &loop, &QEventLoop::quit); loop.exec(); } if (reply->error() == QModbusDevice::NoError) { const QModbusDataUnit unit = reply->result(); for (int i = 0; i < unit.valueCount(); i++) { qDebug() << "Register" << i << ":" << unit.value(i); } } else { qWarning() << "Modbus read request failed:" << reply->errorString(); } reply->deleteLater(); } else { qWarning() << "Failed to send Modbus read request:" << modbusClient.m_modbusClient->errorString(); } ``` 接下来是QModbusDataUnit类的基于QObject的自定义类的实现。QModbusDataUnit类是用于处理Modbus数据单元的类,它包含了数据单元的类型、起始地址和数据值。要基于QObject自定义QModbusDataUnit类,您可以按照以下步骤进行操作: 1.创建一个新的类并继承自QObject类。 ```cpp class MyModbusDataUnit : public QObject { Q_OBJECT public: explicit MyModbusDataUnit(QObject *parent = nullptr); ~MyModbusDataUnit(); Q_INVOKABLE QModbusDataUnit *getDataUnit() const; private: QModbusDataUnit *m_dataUnit; }; ``` 2.在类的构造函数中创建QModbusDataUnit对象,并将其设置为父对象。 ```cpp MyModbusDataUnit::MyModbusDataUnit(QObject *parent) : QObject(parent) { m_dataUnit = new QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 0, 10); m_dataUnit->setValue(0, 1234); m_dataUnit->setValue(1, 5678); // ... } ``` 3.添加自定义的getDataUnit()方法,用于获取QModbusDataUnit对象。 ```cpp QModbusDataUnit *MyModbusDataUnit::getDataUnit() const { return m_dataUnit; } ``` 4.使用自定义的QModbusDataUnit类进行Modbus通信。 ```cpp MyModbusDataUnit writeUnit; QModbusDataUnit *dataUnit = writeUnit.getDataUnit(); dataUnit->setValue(0, 1234); dataUnit->setValue(1, 5678); // ... if (auto *reply = modbusClient.m_modbusClient->sendWriteRequest(*dataUnit, 1)) { if (!reply->isFinished()) { QEventLoop loop; QObject::connect(reply, &QModbusReply::finished, &loop, &QEventLoop::quit); loop.exec(); } if (reply->error() != QModbusDevice::NoError) { qWarning() << "Modbus write request failed:" << reply->errorString(); } reply->deleteLater(); } else { qWarning() << "Failed to send Modbus write request:" << modbusClient.m_modbusClient->errorString(); } ``` 希望这些代码可以帮助您基于QObject自定义QModbusTcpClient类和QModbusDataUnit类。如果您有任何其他问题或需要更多帮助,请随时问我。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值