QT中的信号与槽

一、前言

本文为个人对qt中信号与槽的理解,作用的话是将QT中一个信号与另一个动作或者信号相关连,连接关键为connect()举个例子:

connect(信号发生体,信号,信号接收体,动作或者信号)

#include <QPushButton>


思路:
connect(ui->按钮, &QPushButton::clicked,接收对象,&动作)

详细:
connect(ui->pushButton, &QPushButton::clicked, this, [=]()
        {
            printf("yes!");
        });
分析:
上述信号发送对象是当前UI界面的pushButton的按钮,信号是pushButton进行clicked点击操作,这里写信号的时候,qt会有提示,然后是接收对象this,即当前页面,最后进行槽函数的操作,上述使用的是lambda表达式来表示动作。

下面来分类讲讲:

二、QT自带的信号与槽

1、讲解

在QT中有很多信号与槽是封装好的,在pro文件中添加模块即可使用。如QPushButton属于widget

添加类后在工程中即可使用封装的信号与槽。

有些时候发现没有信号与槽的时候可以往上一级查找,因为QT的类为继承关系,子承父业,儿子可以用老子的公共函数。对应的上图为QAbstractButton的类。

可以找到熟悉的clicked操作:

找到后就可以像其他方法一样直接用了,但是用的时候要注意,QT中使用connect()来把信号与信号、信号与槽关联。

connect的使用方法在你程序中写出connect()时会有提示,也可以查阅QT帮助手册,帮助很重要,可以让学习者快速理解其中的原理。

2、实例方法一

举个简单的例子:

ui新建按钮

ui对应的cpp文件中使用

分析请看本文最前端前言部分,不再赘述。

3、实例方法二

在QT中UI的插件可以有快捷的使用方法,即直接在UI中关联槽函数,不用自己使用connect去连接,举例:

鼠标放在对应按钮,右键,选择转到槽,选择对应的动作,这里选择clicked点击操作。

点击后在ui对应的头文件和cpp文件会生成槽函数:

在on_pushButton_clicked()中写动作。这里的动作可以是槽函数动作,如翻页、打印等等,也可以是信号发送,如另一个按钮的clicked信号发送等。

三、自定义信号与槽

自定义信号与槽在实际工作中使用的最多,其中槽的操作相当于就是写个函数或方法之类的,如:

信号部分需要使用emit来发送信号:

关联(不同写法):

四、举例信号发送数据

举个实际运用中会使用的例子,即我要把数据传输出去,运用信号与槽的方法来传

modbusvariable.h:
#ifndef MODBUSVARIABLE_H
#define MODBUSVARIABLE_H

#include <QWidget>

namespace Ui {
class ModbusVariable;
}

class ModbusVariable : public QWidget
{
    Q_OBJECT

public:
    explicit ModbusVariable(QWidget *parent = nullptr);
    ~ModbusVariable();

private slots:
    void on_pushButton_Yes_clicked();

    void on_pushButton_No_clicked();

private:
    Ui::ModbusVariable *ui;

    QString m_type;
    QString m_varailtype;
    int m_offset;

signals:
    void varailType(QString);
    void Type(QString);
    void varailSignal(void);
    void offsetAddr(int);
};

#endif // MODBUSVARIABLE_H
modbusvariable.cpp
#include "modbusvariable.h"
#include "ui_modbusvariable.h"

#include <QMessageBox>
#include <QDebug>

ModbusVariable::ModbusVariable(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ModbusVariable)
{
    ui->setupUi(this);

    //初始化
    QStringList items,items1;
    items << "Q线圈输出" << "I离散输入" << "MW输入寄存器" << "VW保持寄存器";
    ui->comboBox_ChannelType->addItems(items);
    items1 << "0" << "1" << "2" << "3" << "4"
           << "5" << "6" << "7";
    ui->comboBox_DataType->addItems(items1);
}

ModbusVariable::~ModbusVariable()
{
    delete ui;
}


/*
 * 西门子PLC的modbus映射关系
 *Qm.n = 00001+m*8+n
 * Im.n = 10001+m*8+n
 * MWm = 30001+m/2,m为偶数。
 * VWm = 40001+m/2,m为偶数;DB1.DBWm = 40001+m/2,m为偶数。
*/
void ModbusVariable::on_pushButton_Yes_clicked()
{
    if(!ui->lineEdit_ChannelAddr->text().isEmpty())
    {
        if(ui->comboBox_ChannelType->currentText() == "Q线圈输出")
        {
            m_type = QString("Q""%2"".""%1").arg(ui->comboBox_DataType->currentText()).arg(ui->lineEdit_ChannelAddr->text());
            m_varailtype = QString("Q");
            m_offset = (ui->lineEdit_ChannelAddr->text().toUInt() * 8) + (ui->comboBox_DataType->currentText().toUInt());
        }
        else if(ui->comboBox_ChannelType->currentText() == "I离散输入")
        {
            m_type = QString("I""%1"".""%2").arg(ui->lineEdit_ChannelAddr->text()).arg(ui->comboBox_DataType->currentText());
            m_varailtype = QString("I");
            m_offset = (ui->lineEdit_ChannelAddr->text().toUInt() * 8) + (ui->comboBox_DataType->currentText().toUInt());
        }
        else if(ui->comboBox_ChannelType->currentText() == "MW输入寄存器")
        {
            m_type = QString("MW""%1"".""%2").arg(ui->lineEdit_ChannelAddr->text()).arg(ui->comboBox_DataType->currentText());
            m_varailtype = QString("MW");
            m_offset = (ui->lineEdit_ChannelAddr->text().toUInt() * 8) + (ui->comboBox_DataType->currentText().toUInt());
        }
        else if(ui->comboBox_ChannelType->currentText() == "VW保持寄存器")
        {
            m_type = QString("VW""%1"".""%2").arg(ui->lineEdit_ChannelAddr->text()).arg(ui->comboBox_DataType->currentText());
            m_varailtype = QString("VW");
            m_offset = (ui->lineEdit_ChannelAddr->text().toUInt() * 8) + (ui->comboBox_DataType->currentText().toUInt());
        }
        else
        {
            QMessageBox::critical(this,"错误","选择异常!");
        }
    }
    else
    {
        QMessageBox::warning(this,"警告","通道地址不能为空!");
    }
    emit varailSignal();
    emit varailType(m_type);
    emit Type(m_varailtype);
    emit offsetAddr(m_offset);

}

void ModbusVariable::on_pushButton_No_clicked()
{
   this->close();
}
modbus_page.h:
#ifndef MODBUS_PAGE_H
#define MODBUS_PAGE_H

#include <QWidget>
#include <QModbusRtuSerialMaster>
#include <QModbusDevice>
#include <QSerialPort>
#include <QSerialPortInfo>
#include <QTcpServer>
#include <QTcpSocket>
#include <QModbusTcpClient>
#include <QSqlQuery>
#include <QSqlDatabase>
#include <QSqlError>
#include <QTableWidget>

#include "modbusvariable.h"

namespace Ui {
class modbus_page;
}

class modbus_page : public QWidget
{
    Q_OBJECT

public:
    explicit modbus_page(QWidget *parent = nullptr);
    ~modbus_page();

private:
    Ui::modbus_page *ui;
    QModbusRtuSerialMaster *m_modbusrtumaster;
    QModbusTcpClient *m_modTcpClient;

    int flag;

    QString addressChange(int addr);

    ModbusVariable *modbusvariable;

private slots:
    void on_pushButton_read_clicked();

    void on_pushButton_write_clicked();

    void on_pushButton_connect_clicked();

    void on_pushButton_close_clicked();

    void on_pushButton_read_tcp_clicked();

    void on_pushButton_write_tcp_clicked();
    void on_pushButton_serial_connect_clicked();
    void on_pushButton_add_clicked();
    void on_pushButton_delete_clicked();
    void on_pushButton_clear_clicked();
    void on_pushButton_back_clicked();
    void on_pushButton_sure_clicked();
};

#endif // MODBUS_PAGE_H

modbus_page.cpp:

#include "modbus_page.h"
#include "ui_modbus_page.h"

#include "user.h"

#include <QMessageBox>

modbus_page::modbus_page(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::modbus_page)
{
    ui->setupUi(this);
    /********************************************************************************************************************/
    //网口实例化
    m_modTcpClient = new QModbusTcpClient(this);

    //初始化
    QStringList items,items1,items2;
    items << "Q线圈输出" << "I离散输入" << "MW输入寄存器" << "VW保持寄存器";
    ui->comboBox_flag->addItems(items);

    //获取COM口
    QList<QSerialPortInfo> availablePorts = QSerialPortInfo::availablePorts();
        foreach (const QSerialPortInfo &info, availablePorts)
        {
            //串口名称添加进选项栏
            items1 << info.portName();
        }
    ui->comboBox_flag_COM->addItems(items1);

    //获取波特率
    items2 << "300" << "1200" << "2400" << "4800" << "9600" << "14400"
          << "19200" << "38400" << "57600" << "115200" << "230400" << "460800"
          << "921600" << "1000000";
    ui->comboBox_flag_Baud->addItems(items2);
    /********************************************************************************************************************/
    //获取选择信号
    modbusvariable = new ModbusVariable;
    connect(modbusvariable, &ModbusVariable::varailSignal, this, [=]()
    {
        //表格插入行
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount;
        ui->tableWidget->insertRow(ncount);
        //设置序号
        item[0] = new QTableWidgetItem(QString("%1").arg(i+1));
        ui->tableWidget->setItem(i,0,item[0]);
    });
    connect(modbusvariable, &ModbusVariable::Type, this, [=](QString Type)
    {
        qDebug() << "收到的信号类型是:" << Type;
        //插入变量类型
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[1] = new QTableWidgetItem(Type);
        ui->tableWidget->setItem(i,1,item[1]);
    });
    connect(modbusvariable, &ModbusVariable::varailType, this, [=](QString varailType)
    {
        qDebug() << "收到的信号是:" << varailType;
        //插入变量参数
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[2] = new QTableWidgetItem(varailType);
        ui->tableWidget->setItem(i,2,item[2]);
    });
    connect(modbusvariable, &ModbusVariable::offsetAddr, this, [=](int offset)
    {
        qDebug() << "收到的偏移地址是:" << offset;
        //插入变量参数
        QTableWidgetItem *item[0];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[0] = new QTableWidgetItem(QString("%1").arg(offset));
        ui->tableWidget->setItem(i,3,item[0]);
    });

    /********************************************************************************************************************/
    //画表格
    ui->tableWidget->setColumnCount(4);//设置列数
    QStringList header;
    header << "序号" << "变量类型" << "变量" << "偏移";
    ui->tableWidget->setHorizontalHeaderLabels(header);//设置选项行
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);//选项栏大小固定,不加的时候默认可伸缩
    ui->tableWidget->setColumnWidth(0,50);//设置第一列宽度
    ui->tableWidget->setColumnWidth(1,200);
    ui->tableWidget->setColumnWidth(2,200);
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);//第六行自动填充剩余空间

    ui->tableWidget->verticalHeader()->setVisible(false);//隐藏列表头

    //设置表格字体
    ui->tableWidget->horizontalHeader()->setFont(QFont("Arial", 16));
    ui->tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//水平与垂直居中
    ui->tableWidget->horizontalHeader()->setPalette(QColor(Qt::green));

    ui->tableWidget->horizontalHeaderItem(0)->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);//第一列选项行水平左对齐,垂直居中对齐
    ui->tableWidget->horizontalHeaderItem(1)->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);//第二列选项行水平有对齐,垂直居中对齐
    ui->tableWidget->horizontalHeaderItem(2)->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);//第三列选项行水平有对齐,垂直居中对齐
    ui->tableWidget->horizontalHeaderItem(3)->setTextAlignment(Qt::AlignCenter | Qt::AlignVCenter);//第四列选项行水平有对齐,垂直居中对齐

    ui->tableWidget->setAlternatingRowColors(true);//每行之间颜色交替

    //优化表格
    ui->tableWidget->horizontalHeader()->setStyleSheet(\
        "QHeaderView::section {"\
        "padding: 1px;"\
        "border: none;"\
        "border-bottom: 1px solid rgb(75,120,154);"\
        "border-right: 1px solid rgb(75,120,154);"\
        "background-color: rgb(255,255,0);"\
        "color: rgba(0,0,0,255);"\
        "}"\
        );

    //设置选择行为一行
    ui->tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);//设置为选中一行,而不是单个单元格
    ui->tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);//设置为只能选中一行,而不是能选中多行
    /********************************************************************************************************************/
    //初始化表格,没有表格时建立变量表格
    //打开数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    database.setDatabaseName("QSQLITE.db");
    if(!database.open())
    {
        qDebug() << "创建变量数据库打开失败原因" << database.lastError().text();
    }
    else
    {
        qDebug() << "创建变量数据库连接成功";
    }
    //创建变量表格
    QString createTableStatement = "CREATE TABLE IF NOT EXISTS variable ("
                                  "序号 TEXT NOT NULL,"
                                  "变量类型 TEXT,"
                                  "变量 TEXT,"
                                  "偏移 TEXT)";

    //执行创建表格的SQL查询
    QSqlQuery query1(createTableStatement);

    if (!query1.exec())
    {
        qDebug() << "Error creating table: " << query1.lastError().text();
    }
    else
    {
        qDebug() << "Table 'variable' created successfully.";
    }
    //表格读取数据库数据
    QSqlQuery query("SELECT * FROM variable");
    // 执行查询
    if (!query.exec()) {
        qDebug() << "Failed to execute query: " << query.lastError().text();
        return;
    }
    // 遍历查询结果并打印数据
    while (query.next()) {
        // 四列,分别是"序号", "变量类型", "变量","偏移"
        int num = query.value(0).toInt();
        QString type = query.value(1).toString();
        QString value = query.value(2).toString();
        int offsetaddr = query.value(3).toInt();

        qDebug() << "序号: " << num << ", 变量类型: " << type << ", 变量: " << value << ", 偏移: " << offsetaddr;

        //将数据库内容写进qt创建的表格
        //表格插入行
        QTableWidgetItem *item[4];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount;
        ui->tableWidget->insertRow(ncount);
        //设置序号
        item[0] = new QTableWidgetItem(QString("%1").arg(i+1));
        ui->tableWidget->setItem(i,0,item[0]);
        //插入变量类型
        item[1] = new QTableWidgetItem(type);
        ui->tableWidget->setItem(i,1,item[1]);
        //插入变量参数
        item[2] = new QTableWidgetItem(value);
        ui->tableWidget->setItem(i,2,item[2]);
        //插入偏移
        item[3] = new QTableWidgetItem(QString("%1").arg(offsetaddr));
        ui->tableWidget->setItem(i,3,item[3]);
    }

    //关闭数据库
    database.close();
}

modbus_page::~modbus_page()
{
    delete ui;
}

void modbus_page::on_pushButton_serial_connect_clicked()
{
    //串口连接
    m_modbusrtumaster = new QModbusRtuSerialMaster(this);
    m_modbusrtumaster->setConnectionParameter(QModbusDevice::SerialPortNameParameter, ui->comboBox_flag_COM->currentText());
    m_modbusrtumaster->setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::EvenParity);
    m_modbusrtumaster->setConnectionParameter(QModbusDevice::SerialBaudRateParameter, ui->comboBox_flag_Baud->currentText().toInt());
    m_modbusrtumaster->setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
    m_modbusrtumaster->setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
}


void modbus_page::on_pushButton_read_clicked()
{
    //链接设备
    if(m_modbusrtumaster->state() != QModbusRtuSerialMaster::ConnectedState)
    {
        if(m_modbusrtumaster->connectDevice())
        {
            qDebug() << "串口驱动链接成功";
        }
        else
        {
            qDebug() << "串口驱动链接失败";
        }
    }

    //起始位
    QModbusDataUnit::RegisterType mode;
    if(ui->comboBox_flag->currentText() == "Q线圈输出")
    {
        mode = QModbusDataUnit::Coils;
    }
    else if(ui->comboBox_flag->currentText() == "I离散输入")
    {
        mode = QModbusDataUnit::DiscreteInputs;
    }
    else if(ui->comboBox_flag->currentText() == "MW输入寄存器")
    {
        mode = QModbusDataUnit::InputRegisters;
    }
    else if(ui->comboBox_flag->currentText() == "VW保持寄存器")
    {
        mode = QModbusDataUnit::HoldingRegisters;;
    }
    else
    {
        mode = QModbusDataUnit::HoldingRegisters;
    }
    QModbusDataUnit unit(mode, ui->lineEdit_startaddr->text().toInt(), 1);//读1个位
    //发送请求响应
    QModbusReply *reply = m_modbusrtumaster->sendReadRequest(unit, 1);
    if(reply)
    {
        if(!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, [=]()
            {
                if(reply->result().valueCount()>0)
                {
                    ui->lineEdit_readwrite->setText(QString::number(reply->result().value(0)));
                    ui->lineEdit_address->setText(addressChange(ui->lineEdit_startaddr->text().toInt()));
                }
            });
            return;
        }
        reply->deleteLater();
    }
}

void modbus_page::on_pushButton_write_clicked()
{
    if(m_modbusrtumaster->state() != QModbusRtuSerialMaster::ConnectedState)
    {
        m_modbusrtumaster->connectDevice();
    }

    QModbusDataUnit::RegisterType mode;
    if(ui->comboBox_flag->currentText() == "Q线圈输出")
    {
        mode = QModbusDataUnit::Coils;
    }
    else if(ui->comboBox_flag->currentText() == "I离散输入")
    {
        mode = QModbusDataUnit::DiscreteInputs;
    }
    else if(ui->comboBox_flag->currentText() == "MW输入寄存器")
    {
        mode = QModbusDataUnit::InputRegisters;
    }
    else if(ui->comboBox_flag->currentText() == "VW保持寄存器")
    {
        mode = QModbusDataUnit::HoldingRegisters;
    }
    else
    {
        mode = QModbusDataUnit::HoldingRegisters;
    }
    QModbusDataUnit unit(mode, ui->lineEdit_startaddr->text().toInt(), 1);
    unit.setValue(0, ui->lineEdit_readwrite->text().toUInt());
    m_modbusrtumaster->sendWriteRequest(unit, 1);
}



void modbus_page::on_pushButton_close_clicked()
{
    m_modTcpClient->disconnectDevice();
}

void modbus_page::on_pushButton_connect_clicked()
{
    m_modTcpClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter,
                                           ui->lineEdit_IP->text());
    m_modTcpClient->setConnectionParameter(QModbusDevice::NetworkPortParameter,
                                           ui->lineEdit_port->text());
    if(m_modTcpClient->connectDevice())
    {
        ui->label_stata->setText("连接成功");
    }
    else
    {
        ui->label_stata->setText("未连接");
    }
}

void modbus_page::on_pushButton_read_tcp_clicked()
{
    QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,
                         ui->lineEdit_startaddr_tcp->text().toInt(), 1);//数据单元定义的内容为:类型、起始地址、访问多少位
    QModbusReply *reply = m_modTcpClient->sendReadRequest(unit, 1);//响应的定义内容为:响应的内容;
                                                                   //发送读取请求的内容为:数据单元、sever地址,
                                                                   //其中server地址在modbus工具里面也可以看见能设置
    //将请求的数据读取出来
    if(reply)
    {
        if(!reply->isFinished())
        {
            connect(reply, &QModbusReply::finished, this, [=]()
            {
                if(reply->result().valueCount()>0)
                {
                    ui->lineEdit_readwrite_tcp->setText(QString::number(reply->result().value(0)));
                }
            });
            return;
        }
        reply->deleteLater();
    }
}

void modbus_page::on_pushButton_write_tcp_clicked()
{
    QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,
                         ui->lineEdit_startaddr_tcp->text().toInt(), 1);//数据单元定义的内容为:类型、起始地址、访问多少位
    unit.setValue(0, ui->lineEdit_readwrite_tcp->text().toUInt());

    QModbusReply *reply = m_modTcpClient->sendWriteRequest(unit, 1);
    if(reply)
    {
        reply->deleteLater();
    }
}

QString modbus_page::addressChange(int addr)
{
    /*
     * 西门子PLC的modbus映射关系
     *Qm.n = 00001+m*8+n
     * Im.n = 10001+m*8+n
     * MWm = 30001+m/2,m为偶数。
     * VWm = 40001+m/2,m为偶数;DB1.DBWm = 40001+m/2,m为偶数。
    */
    if(ui->comboBox_flag->currentText() == "Q线圈输出")
    {
        int m,n;
        m = (addr) / 8;
        n = (addr) % 8;
        QString str;
        str = QString("Q%1.%2").arg(m).arg(n);
        return str;
    }
    else if(ui->comboBox_flag->currentText() == "I离散输入")
    {
        int m,n;
        m = (addr) / 8;
        n = (addr) % 8;
        QString str;
        str = QString("I%1.%2").arg(m).arg(n);
        return str;
    }
    else if(ui->comboBox_flag->currentText() == "MW输入寄存器")
    {
        int m;
        m = addr * 2;
        QString str;
        str = QString("MW%1").arg(m);
        return str;
    }
    else if(ui->comboBox_flag->currentText() == "VW保持寄存器")
    {
        int m;
        m = addr * 2;
        QString str;
        str = QString("VW%1").arg(m);
        return str;
    }
    else
    {
       QMessageBox::critical(this,"数据错误","错误!!!!");
    }
}

void modbus_page::on_pushButton_add_clicked()
{
    modbusvariable->show();
}

void modbus_page::on_pushButton_delete_clicked()
{
    //选中单元格
    QList<QTableWidgetItem*> items = ui->tableWidget->selectedItems();//选中的单元格
    int currentrow = ui->tableWidget->row(items.at(0));//选中单元格为哪一行
    //删除选中行数的单元格
    ui->tableWidget->removeRow(currentrow);//删除选中行
    //重新排序序号
    QTableWidgetItem *item[3];
    int ncount;
    ncount = ui->tableWidget->rowCount();//读取表格有多少行
    //设置序号
    for (int i=0;i<ncount;i++)
    {
        item[0] = new QTableWidgetItem(QString("%1").arg(i+1));
        ui->tableWidget->setItem(i,0,item[0]);
    }
}

void modbus_page::on_pushButton_clear_clicked()
{
    //删除所有行
    int ncount = ui->tableWidget->rowCount();
    if (ncount>0)
    {
        for (int i=0;i<ncount;i++)
        {
            ui->tableWidget->removeRow(0);
        }
    }
}

void modbus_page::on_pushButton_back_clicked()
{
    User *u = new User;
    u->show();
    deleteLater();
}

void modbus_page::on_pushButton_sure_clicked()
{
    //确定后将表格存进数据库,并返回上一级页面
    //存放数据库
    //打开数据库
    QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE");
    database.setDatabaseName("QSQLITE.db");
    if(!database.open())
    {
        qDebug() << "变量创建数据库打开失败原因" << database.lastError().text();
    }
    else
    {
        qDebug() << "变量创建数据库连接成功";
    }
    //表格读取数据库数据
    QSqlQuery query("SELECT * FROM variable");
    //清空数据库
    query.exec(QString("DELETE FROM variable"));
    database.transaction();//插入数据库数据需要创建一个事务
    // 获取表格数据
    bool flag;
    for (int row = 0; row < ui->tableWidget->rowCount(); ++row)
    {
        QTableWidgetItem *item = ui->tableWidget->item(row, 0);
        QTableWidgetItem *item1 = ui->tableWidget->item(row, 1);
        QTableWidgetItem *item2 = ui->tableWidget->item(row, 2);
        QTableWidgetItem *item3 = ui->tableWidget->item(row, 3);
        if(item&&item1&&item2&&item3)
        {
            flag = query.exec(QString("insert into variable values('%1','%2','%3','%4')")
                              .arg(item->text()).arg(item1->text()).arg(item2->text()).arg(item3->text()));
        }
        else
        {
            QMessageBox::critical(this,"错误提示","数据不能为空!");
        }
    }

    if(flag)
    {
        // 提交事务
        database.commit();
    }
    else
    {
        //回滚
        database.rollback();
        qDebug() << "Error inserting data: " << query.lastError().text();
    }

    //关闭数据库
    database.close();

    //返回上一级
    User *u = new User;
    u->show();
    deleteLater();
}

上述为自定义一个信号发送的类,将信号发送出去的例子,

signals:
    void varailType(QString);
    void Type(QString);
    void varailSignal(void);
    void offsetAddr(int);

为需要发送的数据。

//获取选择信号
    modbusvariable = new ModbusVariable;
    connect(modbusvariable, &ModbusVariable::varailSignal, this, [=]()
    {
        //表格插入行
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount;
        ui->tableWidget->insertRow(ncount);
        //设置序号
        item[0] = new QTableWidgetItem(QString("%1").arg(i+1));
        ui->tableWidget->setItem(i,0,item[0]);
    });
    connect(modbusvariable, &ModbusVariable::Type, this, [=](QString Type)
    {
        qDebug() << "收到的信号类型是:" << Type;
        //插入变量类型
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[1] = new QTableWidgetItem(Type);
        ui->tableWidget->setItem(i,1,item[1]);
    });
    connect(modbusvariable, &ModbusVariable::varailType, this, [=](QString varailType)
    {
        qDebug() << "收到的信号是:" << varailType;
        //插入变量参数
        QTableWidgetItem *item[3];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[2] = new QTableWidgetItem(varailType);
        ui->tableWidget->setItem(i,2,item[2]);
    });
    connect(modbusvariable, &ModbusVariable::offsetAddr, this, [=](int offset)
    {
        qDebug() << "收到的偏移地址是:" << offset;
        //插入变量参数
        QTableWidgetItem *item[0];
        int ncount,i;
        ncount = ui->tableWidget->rowCount();//读取表格有多少行
        i = ncount - 1;
        item[0] = new QTableWidgetItem(QString("%1").arg(offset));
        ui->tableWidget->setItem(i,3,item[0]);
    });

这个是在使用环境中connect连接,把数据存放进自己写的表格显示出来。

五、总结

信号与槽分谨记发送对象是谁、发送的信号是什么、接收信号是谁、接收信号后的动作是什么即可,connect函数是其中的桥梁 。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值