栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

win 10 QT 5.15.2 modbus QModbusRtuSerialMaster 客户端

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

win 10 QT 5.15.2 modbus QModbusRtuSerialMaster 客户端

原使用在QT5.12版本,用modbus RTU 会出现界面卡死的现象,使用多线程信号传递也有问题,现在换新的5.15版本正常如图:

采用聚英rs232的4入4出设备。

按钮全开写入全部线圈和输入1

//MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include 
#include 
#include
#include 
#include
#include
#include
#include
#include
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_5_clicked();//连接
    void onModbusStateChanged();//状态
    void readModbusINUnit(QModbusDataUnit::RegisterType type, int startAddr, int numbers, int serverID);//DiscreteInputs读取
    void readModbusOUTUnit(QModbusDataUnit::RegisterType type, int startAddr, int numbers, int serverID, bool *isOK);//Coils读取
    void Readinput();//输入连接读取
    void Readout();//输出连接读取
    void textbrowser(QString value);//文本浏览框
    //void showAbout();//关于
    void openApp();//托盘打开
    void  quitApp() ;//托盘退出
    void  pbMin();//最小化
    void  onActivated(QSystemTrayIcon::ActivationReason reason);
    void initConnect();
    void on_pushButton_6_clicked();//断开
    void on_alloffbtn_clicked();//全关
    void on_allonbtn_clicked();//全开
    void Write(int val,int val2,QString val3);//线圈写入
    void RefreshTaskbarIcon();//任务栏图标刷新一遍
    void on_outbtn_1_clicked();//开关1
    void on_outbtn_2_clicked();//开关2
    void on_outbtn_3_clicked();//开关3
    void on_outbtn_4_clicked();//开关4
    //void recvMsg();//接收函数
    void on_IPlineEdit_editingFinished();
    void on_PortlineEdit_editingFinished();
    void Delay(int   time);//延时
    void closeEvent ( QCloseEvent * e );

    void on_comboBox_activated(const QString &arg1);

    void on_comboBox_2_activated(const QString &arg1);

private:
    Ui::MainWindow *ui;
    QModbusRtuSerialMaster* modbusDevice;
    QTimer *timer;
    QTimer* timer_2;
    QMenu*trayIconMenu;//系统托盘菜单
    QSystemTrayIcon*trayIcon;//系统托盘ICO
    QAction*aboutAction ;//建立modbus对象
    QAction*openAction;//建立modbus对象
    QAction*  quitAction;//建立modbus对象
    QSettings* configIni;//建立ini文件对象
    QSettings* name;//建立name ini文件对象
    QUdpSocket *udpsocket;//建立udp对象
    QIntValidator* IntValidator;//校验
    QSerialPort* serial;

};
#endif // MAINWINDOW_H
//por
QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17
QT += serialbus serialport widgets core
requires(qtConfig(combobox))
#QMAKE_CXXFLAGS += /utf-8
QT += concurrent

TARGET = DODI04
RC_ICONS = favicon.ico
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += 
    main.cpp 
    mainwindow.cpp

HEADERS += 
    mainwindow.h

FORMS += 
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

RESOURCES += 
    titl.qrc

 

//mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{

    QString strAppPath = QDir::toNativeSeparators(QCoreApplication::applicationDirPath());//路径获取
    aboutAction = new QAction("关于", this); // 托盘空件创建
    this->aboutAction->setIcon(QIcon::fromTheme("help-about"));//托盘添加关于
    openAction = new QAction("打开", this);
    this->openAction->setIcon(QIcon::fromTheme("media-record"));//托盘添加打开按钮
    quitAction = new QAction(this);//托盘添加退出按钮
    this->quitAction->setText("退出");
    this->quitAction->setIcon(QIcon::fromTheme("application-exit"));// 从系统主题获取图标

    trayIconMenu = new QMenu(this);  // 托盘菜单
    this->trayIconMenu->addAction(aboutAction);//托盘添加关于按钮
    //this->trayIconMenu->addSeparator();
    this->trayIconMenu->addAction(openAction);//托盘添加打开按钮
    this->trayIconMenu->addAction(quitAction);//托盘添加退出按钮
    trayIcon = new QSystemTrayIcon(this); // 托盘图标
    this->trayIcon->setContextMenu(trayIconMenu);
    this->trayIcon->setIcon(QIcon(":/favicon.ico"));
    this->trayIcon->setToolTip("DODI0404D");
    this->trayIcon->show();  // 托盘空件
    this->initConnect();//初始化托盘


    ui->setupUi(this);
    ui->textBrowser->document ()->setMaximumBlockCount (50);//textbrowser 行数限制
    this->setWindowIcon(QIcon(":/favicon.ico"));//标题LOGO
    this->setWindowTitle("DODI04");
    this->setFixedSize(410,425);

    ui->comboBox_2->addItem("9600");
    ui->comboBox_2->addItem("19200");
    ui->comboBox_2->addItem("115200");

    ui->statusbar->setSizeGripEnabled(false);//去掉状态栏右下角的三角
    QLabel *permanent=new QLabel(this);//状态栏版本信息
    //permanent->setFrameStyle(QFrame::Box|QFrame::Sunken);//box 样式
    permanent->setText(tr("版本V1.0"));
    permanent->setStyleSheet(QString("QStatusBar::item{border: 0px}")); // 不显示label的边框
    //permanent->setOpenExternalLinks(true);//设置可以打开网站链接
    ui->statusbar->addPermanentWidget(permanent);//显示永久信息
    serial = new QSerialPort(this);
    modbusDevice = new QModbusRtuSerialMaster(this);
    connect(modbusDevice, &QModbusClient::errorOccurred, [this](QModbusDevice::Error) {//连接modbus error
        ui->statusbar->showMessage(modbusDevice->errorString());
        if (modbusDevice->errorString() != NULL){
//            on_pushButton_6_clicked();
//            this->Delay(100);
//            on_pushButton_5_clicked();
        }
    });
    connect(modbusDevice, &QModbusClient::stateChanged,
            this, &MainWindow::onModbusStateChanged); //连接状态发生改变时处理函数(connect or discennect)
    timer = new QTimer(this);//建立读取timer
    connect(timer, SIGNAL(timeout()), this, SLOT(Readinput()));//连接
    timer->setTimerType(Qt::PreciseTimer);//精度
    timer_2 = new QTimer(this);//建立刷新ICON
    connect(timer_2, SIGNAL(timeout()), this, SLOT(RefreshTaskbarIcon()));//连接刷新ICON
    timer_2->start(1500);


//    QString IPval;
//    QString localHostName = QHostInfo::localHostName();//获取本机的IP地址(可能有多条)qDebug() << "localHostName" << localHostName;
//    QHostInfo info = QHostInfo::fromName(localHostName);//只输出IPv4地址  qDebug()<<"IP Address:"<< info.addresses();
//    QString *add =new QString();
//    foreach(QHostAddress address,info.addresses())
//    {
//        if(address.protocol() == QAbstractSocket::IPv4Protocol)
//            IPval = address.toString();
//    }
    QFileInfo path(strAppPath + "\config\params.ini");
    if (path.isFile() == false){
        (QMessageBox::information(NULL, "", "找不到配置config.ini文件"));}

    configIni = new QSettings(strAppPath + "\config\params.ini", QSettings::IniFormat, this);//配置文件读取
    configIni->setIniCodec("UTF-8");
    //ui->lineEdit->adjustSize();//自动大小
    ui->IPlineEdit->setText(configIni->value("config/IP").toString());//ip
    ui->PortlineEdit->setText(configIni->value("config/PORT").toString());// port

    //获取可以用的串口
    QList serialPortInfos = QSerialPortInfo::availablePorts();
    for (const QSerialPortInfo &serialPortInfo : serialPortInfos)
    {
            //串口信息
            //this->textbrowser("描述:n"+serialPortInfo.description()) ;
            //this->textbrowser("制造商:n"+serialPortInfo. manufacturer());
            //this->textbrowser("端口:n"+serialPortInfo. portName()) ;
            //this->textbrowser("产品标识符:n"+QString::number(serialPortInfo. productIdentifier()));
            //this->textbrowser("序列号:n"+ serialPortInfo. serialNumber());
            //this->textbrowser( serialPortInfo. systemLocation()) ;
            ui->comboBox->addItem(serialPortInfo. portName());
            if(serialPortInfo. portName()== configIni->value("config/COM").toString()){
                 ui->comboBox->removeItem(-1);
            }
        if(serialPortInfo. portName() ==NULL){
            (QMessageBox::warning(NULL, "", "检查COM是否存在"));
        }
    }
    ui->comboBox_2-> insertItem(0,configIni->value("config/Baud").toString());
    ui->comboBox_2->setCurrentIndex(0);
    IntValidator = new QIntValidator(this);//端口校验
    IntValidator->setRange(0, 65535);//端口限制(0,65535)
    ui->PortlineEdit->setValidator(IntValidator);

    QRegExp rx("^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");//IP校验
    QRegExpValidator *ip1 = new QRegExpValidator(rx, this);
    ui->IPlineEdit->setValidator(ip1);

    QFileInfo path1(strAppPath + "\config\name.ini");
    if (path1.isFile() == false){
        (QMessageBox::information(NULL, "", "找不到配置name.ini文件"));}

    name = new QSettings(strAppPath + "\config\name.ini", QSettings::IniFormat, this);//配置文件读取
    name->setIniCodec("UTF-8");
    ui->outbtn_1->setText(name->value("config/name1").toString()+"开");
    ui->outbtn_2->setText(name->value("config/name2").toString()+"开");
    ui->outbtn_3->setText(name->value("config/name3").toString()+"开");
    ui->outbtn_4->setText(name->value("config/name4").toString()+"开");
    ui->allonbtn->setText(name->value("config/name5").toString()+"全开");
    ui->alloffbtn->setText(name->value("config/name6").toString()+"全关");
    udpsocket = new QUdpSocket(this);//新建UDP
    const quint16 PORT = configIni->value("config/PORT").toInt();//监听端口
    this->udpsocket->bind(QHostAddress(configIni->value("config/IP").toString()), PORT);
    connect(udpsocket, SIGNAL(readyRead()), this, SLOT(recvMsg()));//连接接收函数
    if (udpsocket->errorString() != "Unknown error")//socket erro 捕捉
    {
        QMessageBox::information(NULL, "", udpsocket->errorString());
    }
    ui->inlabel->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                               "background-position:top right;"
                               "background-origin:content;"
                               "background-repeat:none;"
                               "}");
    ui->inlabel_2->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                 "background-position:top right;"
                                 "background-origin:content;"
                                 "background-repeat:none;"
                                 "}");
    ui->inlabel_3->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                 "background-position:top right;"
                                 "background-origin:content;"
                                 "background-repeat:none;"
                                 "}");
    ui->inlabel_4->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                 "background-position:top right;"
                                 "background-origin:content;"
                                 "background-repeat:none;"
                                 "}");

}


void   MainWindow::Delay(int   time)//time*1000为秒数
{
    clock_t  now  = clock();
    while(clock()-nowhasPendingDatagrams())
//    {
//        QByteArray datagram;
//        datagram.resize(udpsocket->pendingDatagramSize());
//        udpsocket->readDatagram(datagram.data(),datagram.size());
//        QString str = datagram;
//        this->textbrowser("接收到数据:"+str);

//        QStringList list1 = str.split(";"); // 注意,如果str是空字符串,list1会增加一个空字符串到列表里,其size=1,
//        for(int i=0;iWrite(0,4,list2[0]);

//            }

//            list2.clear();//清空列表2
//        }

//        list1.clear();//清空列表1
//    }

//    return;
//}




void MainWindow::RefreshTaskbarIcon()//任务栏图标刷新
{
    //任务栏窗口
    HWND hShellTrayWnd = ::FindWindow(L"Shell_TrayWnd",NULL);
    //任务栏右边托盘图标+时间区
    HWND hTrayNotifyWnd = ::FindWindowEx(hShellTrayWnd,0,L"TrayNotifyWnd",NULL);
    //不同系统可能有可能没有这层
    HWND hSysPager = ::FindWindowEx(hTrayNotifyWnd,0,L"SysPager",NULL);
    //托盘图标窗口
    HWND hToolbarWindow32;

    if (hSysPager)
    {
        hToolbarWindow32 = ::FindWindowEx(hSysPager,0,L"ToolbarWindow32",NULL);
    }
    else
    {
        hToolbarWindow32 = ::FindWindowEx(hTrayNotifyWnd,0,L"ToolbarWindow32",NULL);
    }
    if (hToolbarWindow32)
    {
        RECT r;
        ::GetWindowRect(hToolbarWindow32,&r);
        int width = r.right - r.left;
        int height = r.bottom - r.top;
        //从任务栏中间从左到右 MOUSEMOVE一遍,所有图标状态会被更新
        for (int x = 1; xvalue("config/AutoHide").toString() == "True")//隐藏复选框
    {
        this->pbMin();
    }

    if (configIni->value("config/AutoOPen").toString() == "True")//开启自动连接
    {
        this->on_pushButton_5_clicked();
    }

    this->timer_2->stop();
    return;
}


void MainWindow::onModbusStateChanged()//modbusl连接状态
{
    //判断Modbus设备连接是否处于连接状态
    if(modbusDevice->state() == QModbusDevice::ConnectedState)
    {
        ui->statusbar->showMessage("成功连接到设备");
        this->textbrowser("成功连接到设备");
        this->timer->start(40);//连接读取
        ui->pushButton_5->setEnabled(false);
    }

    if (modbusDevice->state() == QModbusDevice::ConnectingState){
        ui->statusbar->showMessage("正在连接");
        this->textbrowser("正在连接");
    }

    if (modbusDevice->state() == QModbusDevice::UnconnectedState){
        ui->statusbar->showMessage("未连接设备");
        this->textbrowser("未连接设备");
        ui->pushButton_5->setEnabled(true);
        this->timer->stop();
    }
    return;
}

void MainWindow::closeEvent ( QCloseEvent * e )
{
    modbusDevice->disconnect();
    modbusDevice->deleteLater();
    this->RefreshTaskbarIcon();
}


MainWindow::~MainWindow()
{
    delete ui;

}


void MainWindow::on_pushButton_5_clicked()//连接按钮
{
    if (!modbusDevice)
        return;
    statusBar()->clearMessage();
    if ( !modbusDevice->state() != QModbusDevice::ConnectedState) {
        modbusDevice->setConnectionParameter(QModbusDevice::SerialPortNameParameter,
                                             ui->comboBox->currentText());
        modbusDevice->setConnectionParameter(QModbusDevice::SerialParityParameter,
                                             QSerialPort::NoParity);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialBaudRateParameter,
                                             ui->comboBox_2->currentText().toInt());
        modbusDevice->setConnectionParameter(QModbusDevice::SerialDataBitsParameter,
                                             QSerialPort::Data8);
        modbusDevice->setConnectionParameter(QModbusDevice::SerialStopBitsParameter,
                                             QSerialPort::OneStop);
        modbusDevice->setTimeout(100);
        modbusDevice->setNumberOfRetries(2);
        if (!modbusDevice->connectDevice()) {
            statusBar()->showMessage(tr("Connect failed: ") + modbusDevice->errorString());
        }
    }
    else
    {modbusDevice->disconnectDevice();}
}


void MainWindow::on_pushButton_6_clicked()//断开
{
    modbusDevice->disconnectDevice();
    serial->close();
    serial->clear();
    ui->statusbar->showMessage(tr("设备已断开"));
    this->textbrowser("设备已断开");
}

void MainWindow::Readinput()//读取DI

{

    //    QFuture future = QtConcurrent::run(this,&MainWindow::readModbusINUnit,QModbusDataUnit::DiscreteInputs,0, 4, 1);
    //    while (future.isFinished()) {
    //        QApplication::processEvents(QEventLoop::AllEvents);
    //        if(!future.isFinished())
    //                {
    //                    QApplication::processEvents(QEventLoop::AllEvents, 80);
    //                }
    //    }

    bool isOK;
    this->readModbusINUnit(QModbusDataUnit::DiscreteInputs, 0, 4, 1);//输入读取
    this->readModbusOUTUnit(QModbusDataUnit::Coils, 0, 4, 1, &isOK);//线圈读取
    //this->update();
    return;

}

void MainWindow::readModbusINUnit(QModbusDataUnit::RegisterType type, int startAddr, int numbers, int serverID)
{
    QApplication::processEvents(QEventLoop::AllEvents);
    QString value;
    QList list ={};
    QList list1 = {};
    QVector results ;
    results.clear();
    if (modbusDevice->state() != QModbusDevice::ConnectedState) {
        return ;
    }
    QModbusDataUnit readUnit(type, startAddr, static_cast(numbers));
    auto *reply =modbusDevice->sendReadRequest(readUnit, serverID);
    if (!reply->isFinished()) {
        QEventLoop loop;
        connect(reply, &QModbusReply::finished,&loop,&QEventLoop::quit);
        loop.exec();
    }
    if (reply->error() == QModbusDevice::NoError) {
        const QModbusDataUnit unit = reply->result();
        QString strType;
        switch (type){
        //case QModbusDataUnit::Coils: strType = "Coils"; break;
        case QModbusDataUnit::DiscreteInputs: strType = "DiscreteInputs"; break;
        }
        if (strType == "DiscreteInputs"){// 输入读取
            for(int i = 0;i<  unit.values().count();i++){
                int a = unit.values()[i];
                list.append((a));
                list1.append(QString::number(a));
            }
            if(list1[0]!= "0" || list1[1]!= "0" || list1[2]!= "0" || list1[3]!= "0"){
                QString val = list1[0]+list1[1]+list1[2]+list1[3];
                this->textbrowser("DI数据:"+val);
                QHostAddress addr(ui->IPlineEdit->text());//按钮发送息信
                QByteArray msg;
                msg.append(val);//
                //udpsocket->writeDatagram(msg, addr, (quint16)ui->PortlineEdit->text().toInt());
                msg = NULL;
            }
            if(list1[0]== "1" ){ui->inlabel->setStyleSheet("QLabel{""background-image:url(:/icon.png);"
                                                           "background-position:top right;"
                                                           "background-origin:content;"
                                                           "background-repeat:none;"
                                                           "}");}
            if(list1[0]!= "1" ){ui->inlabel->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                                           "background-position:top right;"
                                                           "background-origin:content;"
                                                           "background-repeat:none;"
                                                           "}");}
            if(list1[1]== "1"){ui->inlabel_2->setStyleSheet("QLabel{""background-image:url(:/icon.png);"
                                                            "background-position:top right;"
                                                            "background-origin:content;"
                                                            "background-repeat:none;"
                                                            "}");}
            if(list1[1]!= "1" ){ui->inlabel_2->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                                             "background-position:top right;"
                                                             "background-origin:content;"
                                                             "background-repeat:none;"
                                                             "}");}
            if(list1[2]== "1"){ui->inlabel_3->setStyleSheet("QLabel{""background-image:url(:/icon.png);"
                                                            "background-position:top right;"
                                                            "background-origin:content;"
                                                            "background-repeat:none;"
                                                            "}");}
            if(list1[2]!= "1" ){ui->inlabel_3->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                                             "background-position:top right;"
                                                             "background-origin:content;"
                                                             "background-repeat:none;"
                                                             "}");}
            if(list1[3]== "1"){ui->inlabel_4->setStyleSheet("QLabel{""background-image:url(:/icon.png);"
                                                            "background-position:top right;"
                                                            "background-origin:content;"
                                                            "background-repeat:none;"
                                                            "}");}
            if(list1[3]!= "1" ){ui->inlabel_4->setStyleSheet("QLabel{""background-image:url(:/icon2.png);"
                                                             "background-position:top right;"
                                                             "background-origin:content;"
                                                             "background-repeat:none;"
                                                             "}");}

            list.clear();
            list1.clear();

        }
        results = unit.values();
    }
    delete reply;
    return ;
}

void MainWindow::Readout()
{
    bool isOK;
    this->readModbusOUTUnit(QModbusDataUnit::Coils, 0, 4, 1, &isOK);//线圈读取
    return;
}

void MainWindow::readModbusOUTUnit(QModbusDataUnit::RegisterType type, int startAddr, int numbers, int serverID, bool *isOK)
{

    QList list ={};
    QList list1 = {};
    QVector results;
    results.clear();
    if (modbusDevice->state() != QModbusDevice::ConnectedState) {
        *isOK = false;
        return ;
    }

    QModbusDataUnit readUnit(type, startAddr, static_cast(numbers));
    auto *reply = modbusDevice->sendReadRequest(readUnit, serverID);
    if (!reply->isFinished()) {
        QEventLoop loop;
        connect(reply, &QModbusReply::finished,&loop,&QEventLoop::quit);
        loop.exec();
    }

    if (reply->error() == QModbusDevice::NoError) {
        const QModbusDataUnit unit = reply->result();
        QString strType;
        switch (type){
        case QModbusDataUnit::Coils: strType = "Coils"; break;
        case QModbusDataUnit::DiscreteInputs: strType = "DiscreteInputs"; break;
        }
        if (strType == "Coils"){//线圈读取
            //qDebug()<outbtn_1->setText(name->value("config/name1").toString()+"关");
                ui->outbtn_1->setStyleSheet("background: rgb(255,0,0)");}//开关按钮背景1
            else{ ui->outbtn_1->setText(name->value("config/name1").toString()+"开");
                ui->outbtn_1->setStyleSheet("background: rgb(255,255,255)");}
            if(list[1] == 1){ ui->outbtn_2->setText(name->value("config/name2").toString()+"关");
                ui->outbtn_2->setStyleSheet("background: rgb(255,0,0)");}//开关按钮背景2
            else{ ui->outbtn_2->setText(name->value("config/name2").toString()+"开");
                ui->outbtn_2->setStyleSheet("background: rgb(255,255,255)");}
            if(list[2] == 1){ ui->outbtn_3->setText(name->value("config/name3").toString()+"关");
                ui->outbtn_3->setStyleSheet("background: rgb(255,0,0)");}//开关按钮背景3
            else{ ui->outbtn_3->setText(name->value("config/name3").toString()+"开");
                ui->outbtn_3->setStyleSheet("background: rgb(255,255,255)");}
            if(list[3] == 1){ ui->outbtn_4->setText(name->value("config/name4").toString()+"关");
                ui->outbtn_4->setStyleSheet("background: rgb(255,0,0)");}//开关按钮背景4
            else{ ui->outbtn_4->setText(name->value("config/name4").toString()+"开");
                ui->outbtn_4->setStyleSheet("background: rgb(255,255,255)");}
            if(list[0] == 1&& list[1] == 1&& list[2] == 1&& list[3] == 1){
                ui->allonbtn->setStyleSheet("background: rgb(255,0,0)");}//全开按钮背景
            else{
                ui->allonbtn->setStyleSheet("background: rgb(255,255,255)");}//全关按钮背景
            if(list[0] == 0&& list[1] == 0&& list[2] == 0&& list[3] == 0){
                ui->alloffbtn->setStyleSheet("background: rgb(255,0,0)");}//全开按钮背景
            else{
                ui->alloffbtn->setStyleSheet("background: rgb(255,255,255)");}//全关按钮背景
            list.clear();
            list1.clear();

        }

        *isOK = true;
        results = unit.values();

    } else {
        *isOK = false;

    }

    delete reply;
    return ;
}


void MainWindow::textbrowser(QString value)//textbrower 显示
{
     ui ->textBrowser->insertPlainText(value+"n");
    QTextCursor ta = ui->textBrowser->textCursor();
    ta.movePosition(QTextCursor::End);
    ui ->textBrowser->setTextCursor(ta);
    return;
}

void MainWindow::initConnect()//托盘函数
{
    //connect(this->aboutAction, SIGNAL(triggered()), this, SLOT(showAbout()));
    connect(this->aboutAction, &QAction::triggered, qApp, &QApplication::aboutQt);
    connect(this->openAction, SIGNAL(triggered()), this, SLOT(openApp()));
    connect(this->quitAction, SIGNAL(triggered()), this, SLOT(quitApp()));
    return ;
}

void MainWindow::openApp()  //# 托盘打开程序
{
    this->showNormal();
    return;
}

void  MainWindow::quitApp() //# 托盘推出
{
    this->close();
    return;
}

void  MainWindow::pbMin()// 最小化到托盘
{

    this->setWindowState(Qt::WindowMinimized);
    connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::onActivated);
    //trayIcon->show();
    return;
}

void  MainWindow::onActivated(QSystemTrayIcon::ActivationReason reason)//双击显示软件
{
    if (reason == QSystemTrayIcon::DoubleClick){
        this->showNormal();
    }
    return;

}//托盘打开

void MainWindow::on_alloffbtn_clicked()//全关
{

    this->Write(0,4,"0000");
    return;
}


void MainWindow::on_allonbtn_clicked()//全开
{
    this->Write(0,4,"1111");
    return;

}


void MainWindow::Write(int val,int val2,QString val3)
{
    QList list= {};
    QString str = NULL;
    quint16 hex1;
    quint16 number1 = static_cast(val2); //C++中的数据类型转换
    QModbusDataUnit writeUnit(QModbusDataUnit::Coils,val,number1);//1起始路数,4尾路数,1为单路数
    for (uint i1 = 0; i1 < writeUnit.valueCount(); i1++) {
        //int j1 = j1*i1;
        QString stt = val3.mid (i1,1);
        bool ok;
        hex1 =stt.toInt(&ok,16);//将textedit中读取到的数据转换为16进制发送
        writeUnit.setValue(i1,hex1);//设置发送数据
    }

    for(int i = 0;i<  writeUnit.values().count();i++){
        int a = writeUnit.values()[i];
        list.append(QString::number(a));
    }
    str = list.join(",");
    this->textbrowser("发送DO数据:"+str);
    str = nullptr;
    if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 1)) {//  sendWriteRequest是向服务器写数据
        if (!reply->isFinished()) {
            connect(reply, &QModbusReply::finished, this, [this, reply]() {
                if (reply->error() == QModbusDevice::ProtocolError) {
                    this->textbrowser(reply->errorString());}
                else if (reply->error() != QModbusDevice::NoError) {
                    this->textbrowser(reply->errorString());}
                reply->deleteLater();});}
        else {reply->deleteLater();}}
    else { this->textbrowser ( modbusDevice->errorString());
    }
    list.clear();
    return ;
}


void MainWindow::on_outbtn_1_clicked()//开关1
{
    if(ui->outbtn_1->text().mid(ui->outbtn_1->text().length()-1,1) =="关"){
        this->Write(0,1,"0");
    }
    if(ui->outbtn_1->text().mid(ui->outbtn_1->text().length()-1,1) =="开"){
        this->Write(0,1,"1");
    }
    return;
}

void MainWindow::on_outbtn_2_clicked()//开关2
{
    if(ui->outbtn_2->text().mid(ui->outbtn_2->text().length()-1,1) =="关"){
        this->Write(1,1,"0");
    }
    if(ui->outbtn_2->text().mid(ui->outbtn_2->text().length()-1,1) =="开"){
        this->Write(1,1,"1");
    }
    return;
}

void MainWindow::on_outbtn_3_clicked()//开关3
{
    if(ui->outbtn_3->text().mid(ui->outbtn_3->text().length()-1,1) =="关"){
        this->Write(2,1,"0");
    }
    if(ui->outbtn_3->text().mid(ui->outbtn_3->text().length()-1,1) =="开"){
        this->Write(2,1,"1");
    }
    return;
}

void MainWindow::on_outbtn_4_clicked()//开关4
{
    if(ui->outbtn_4->text().mid(ui->outbtn_4->text().length()-1,1) =="关"){
        this->Write(3,1,"0");
    }
    if(ui->outbtn_4->text().mid(ui->outbtn_4->text().length()-1,1) =="开"){
        this->Write(3,1,"1");
    }
    return;
}

void MainWindow::on_IPlineEdit_editingFinished()//ip 编辑框
{
    if (ui->IPlineEdit->text() == NULL)
    {
        ui->IPlineEdit->setText(configIni->value("config/IP").toString());
    }
    else
    {
        configIni->beginGroup("config");
        configIni->setValue("IP", ui->IPlineEdit->text());
        configIni->endGroup();
    }
    return;
}


void MainWindow::on_PortlineEdit_editingFinished()//port 编辑框
{
    if (ui->PortlineEdit->text() == NULL)
    {
        ui->PortlineEdit->setText(configIni->value("config/PORT").toString());
    }
    else
    {
        configIni->beginGroup("config");
        configIni->setValue("PORT", ui->PortlineEdit->text());
        configIni->endGroup();
    }
    return;
}


void MainWindow::on_comboBox_activated(const QString &arg1)//baud 下拉框
{

       configIni->beginGroup("config");
       configIni->setValue("COM", arg1);
       configIni->endGroup();
    qDebug()setValue("Baud", arg1);
    configIni->endGroup();
 qDebug()<
//mian.cpp
#include "mainwindow.h"
#include 
#include


int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    a.setStyle(QStyleFactory::create("fusion"));
    MainWindow w;
    w.show();
    return a.exec();
}

以上完整代码,工程链接

QT5.15modbusRTU4路输入输出-C++文档类资源-CSDN下载

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/947430.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号