Qt 一个信号对应多个槽以及多个槽对应一个信号示例

2 篇文章 0 订阅
1 篇文章 0 订阅

这其中存在两个最基本的问题:

1.一个信号对应多个槽时,槽函数的执行顺序是怎样的???
2.多个信号对应一个槽时,如何在槽函数中判断信号的发出者是谁(来自哪个类的对象)?

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <tcpclient.h>
#include <spcomm.h>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSettings>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

signals:
    void connectToTcp(QString&, int&);

    void disConnectToTcp();

protected:
    void closeEvent(QCloseEvent *event);

public slots:
    void connectOk();

    void disConnectOk();

    void recevierOKNGData(const QString&);

    void recevierQrCodeData(const QString&);

    void readComData();

    void tryConnect();

private slots:
    void on_conBtn_clicked();

    void on_disConBtn_clicked();

    void on_openBtn_clicked();

    void on_closeBtn_clicked();

    void on_conBtn_2_clicked();

    void on_disConBtn_2_clicked();

private:
    Ui::MainWindow *ui;
    tcpClient *m_tcpClient, *m_tcpClient1;
    SPComm *m_adam;
    void readIpCfg();
    void writeIpCfg();
    QString decBin(long data);
};
#endif // MAINWINDOW_H

mainwindow.cpp

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

#pragma execution_character_set("utf-8")

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    readIpCfg();
    m_tcpClient = new tcpClient(this);
    m_tcpClient->start();

    m_tcpClient1 = new tcpClient(this);
    m_tcpClient1->start();

    m_adam = new SPComm();

    QTimer* comT = new QTimer(this);
    comT->start(200);

    QTimer* connectT = new QTimer(this);
    connectT->start(500);

    m_tcpClient->tcpSocket->setObjectName("okng");
    m_tcpClient1->tcpSocket->setObjectName("qrcode");

    connect(m_tcpClient, &tcpClient::sendTcpMsg, this, &MainWindow::recevierOKNGData);
    connect(m_tcpClient1, &tcpClient::sendTcpMsg, this, &MainWindow::recevierQrCodeData);
    connect(m_tcpClient->tcpSocket,&QTcpSocket::connected, this, &MainWindow::connectOk);
    connect(m_tcpClient->tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::disConnectOk);
    connect(m_tcpClient1->tcpSocket,&QTcpSocket::connected, this, &MainWindow::connectOk);
    connect(m_tcpClient1->tcpSocket,&QTcpSocket::disconnected,this,&MainWindow::disConnectOk);
    connect(this, &MainWindow::connectToTcp, m_tcpClient, &tcpClient::connectServer);
    connect(this, &MainWindow::disConnectToTcp, m_tcpClient, &tcpClient::disConnectServer);
    connect(this, &MainWindow::connectToTcp, m_tcpClient1, &tcpClient::connectServer);
    connect(this, &MainWindow::disConnectToTcp, m_tcpClient1, &tcpClient::disConnectServer);
    connect(comT, SIGNAL(timeout()), this , SLOT(readComData()));
    connect(connectT, SIGNAL(timeout()), this , SLOT(tryConnect()));
}

MainWindow::~MainWindow()
{
    m_tcpClient->setRun();
    m_tcpClient->wait();
    m_tcpClient1->setRun();
    m_tcpClient1->wait();
    delete m_adam;
    delete ui;
}

void MainWindow::readIpCfg()
{
    QSettings iniRead("C:/services/tcpokng/tcpConfig.ini", QSettings::IniFormat);
    iniRead.beginGroup("com");
    ui->comLE->setText(iniRead.value("port").toString());
    iniRead.endGroup();
    iniRead.beginGroup("tcpokng");
    ui->iplineEdit->setText(iniRead.value("ip").toString());
    ui->portlineEdit->setText(iniRead.value("port").toString());
    iniRead.endGroup();
    iniRead.beginGroup("tcpqrcode");
    ui->iplineEdit_2->setText(iniRead.value("ip").toString());
    ui->portlineEdit_2->setText(iniRead.value("port").toString());
    iniRead.endGroup();

}

void MainWindow::writeIpCfg()
{
    QSettings iniwrite("C:/services/tcpokng/tcpConfig.ini",QSettings::IniFormat);

    iniwrite.beginGroup("com");
    iniwrite.setValue("port",ui->comLE->text().trimmed());
    iniwrite.endGroup();
    iniwrite.beginGroup("tcpokng");
    iniwrite.setValue("ip",ui->iplineEdit->text().trimmed());
    iniwrite.setValue("port",ui->portlineEdit->text().trimmed());
    iniwrite.endGroup();
    iniwrite.beginGroup("tcpqrcode");
    iniwrite.setValue("ip",ui->iplineEdit_2->text().trimmed());
    iniwrite.setValue("port",ui->portlineEdit_2->text().trimmed());
    iniwrite.endGroup();

}

void MainWindow::connectOk()
{
    QString obj = QObject::sender()->objectName();
    qDebug()<<obj;
    if(obj == "okng")
    {
        ui->conBtn->setEnabled(false);
        ui->disConBtn->setEnabled(true);
    }
    else if(obj == "qrcode")
    {
        ui->conBtn_2->setEnabled(false);
        ui->disConBtn_2->setEnabled(true);
    }
}

void MainWindow::disConnectOk()
{
    QString obj = QObject::sender()->objectName();
    if(obj == "okng")
    {
        ui->conBtn->setEnabled(true);
        ui->disConBtn->setEnabled(false);
    }
    else if(obj == "qrcode")
    {
        ui->conBtn_2->setEnabled(true);
        ui->disConBtn_2->setEnabled(false);
    }

}

void MainWindow::recevierOKNGData(const QString& data)
{
    //解析从OKNG获取到的JSON字符串
    QJsonDocument doc = QJsonDocument::fromJson(data.toUtf8());
    QJsonObject obj = doc.object();
    auto iter = obj.find("panel");
    auto iter1 = obj.find("ok");
    if((iter != obj.end()) && (iter1 != obj.end()))
    {
        int panel  = iter.value().toInt();
        bool ok = iter1.value().toBool();
        ui->textEdit->append(QString("From OKNG:%1->%2").arg(panel).arg(ok?"OK":"NG"));
        if(panel == ui->qrValueLE->text().toInt())
        {
            std::string _signal;
            if(ok)
                _signal = "#01c010.000" + std::string("\x0d");
            else
                _signal = "#01c110.000" + std::string("\x0d");
            m_adam->writeData(_signal);
            ui->textEdit->append(QString("To Adam:%1").arg(QString::fromStdString(_signal).trimmed()));
        }
    }
}

void MainWindow::recevierQrCodeData(const QString& data)
{
    //从读码器得到的当前面板数值
    ui->qrValueLE->setText(data);
    ui->textEdit->append(QString("From QrCode:%1").arg(data));
    //发送给OKNG,获取结果
    m_tcpClient->sendData(data.toStdString());
    ui->textEdit->append(QString("To OKNG:%1").arg(data));
}

void MainWindow::readComData()
{
    if(!m_adam->isOpen())
        return;
    QString data = m_adam->readData().trimmed();
    if(!data.isEmpty())
    {
        ui->textEdit->append(QString("From Adam:%1").arg(data));
    }
}

//To convert data into binary
QString MainWindow::decBin(long data)
{
    long sum;
    QString Sendata = "";
    QString myStr = "";
    int Lens;
    sum = data;
    while(sum > 0)
    {
        myStr = sum % 2;
        sum = sum / 2;
        Sendata += myStr;
    }

//        myStr = sum Mod 2
//        sum = sum \ 2
//        Sendata = Sendata & myStr
//    Loop
//    Lens = Sendata.length();
//    Select Case Lens
//        Case 1
//            Sendata = Sendata & "000"
//        Case 2
//            Sendata = Sendata & "00"
//        Case 3
//            Sendata = Sendata & "0"
//        Case 4
//            Sendata = Sendata
//        Case Else
//            Sendata = "0000"
//    End Select
//    Sendata = StrReverse(Sendata)
//    Return Sendata
    return "";
}



void MainWindow::tryConnect()
{
    on_conBtn_clicked();
    on_conBtn_2_clicked();
    on_openBtn_clicked();
}

void MainWindow::on_conBtn_clicked()
{
    if(m_tcpClient->tcpSocket->state() == QAbstractSocket::ConnectedState)
        return;
    QString ip = ui->iplineEdit->text().trimmed();
    int port = ui->portlineEdit->text().toInt();
    this->setObjectName("okng");
    emit connectToTcp(ip, port);
}

void MainWindow::on_disConBtn_clicked()
{
    this->setObjectName("okng");
    emit disConnectToTcp();      
}


void MainWindow::on_openBtn_clicked()
{
    if(m_adam->isOpen())
           return;
     m_adam->setBaudRate(9600);
     m_adam->setPortName(ui->comLE->text().trimmed());
     if(m_adam->open())
     {
         qDebug() << "打开串口成功";
         ui->openBtn->setEnabled(false);
         ui->closeBtn->setEnabled(true);
     }
     else
         qWarning()<<"打开串口失败";
}

void MainWindow::on_closeBtn_clicked()
{
    if(m_adam->isOpen())
    {
        m_adam->close();
        qDebug()<<"关闭串口成功";
        ui->closeBtn->setEnabled(false);
        ui->openBtn->setEnabled(true);
    }
}

void MainWindow::on_conBtn_2_clicked()
{
    if(m_tcpClient1->tcpSocket->state() == QAbstractSocket::ConnectedState)
        return;
    QString ip = ui->iplineEdit_2->text().trimmed();
    int port = ui->portlineEdit_2->text().toInt();
    this->setObjectName("qrcode");
    emit connectToTcp(ip, port);
}

void MainWindow::on_disConBtn_2_clicked()
{
    this->setObjectName("qrcode");
    emit disConnectToTcp();
}

void MainWindow::closeEvent(QCloseEvent *event)
{
   m_adam->close();
   this->setObjectName("okng");
   emit disConnectToTcp();
   this->setObjectName("qrcode");
   emit disConnectToTcp();
   writeIpCfg();
   QMainWindow::closeEvent(event);
}

tcpClient.h

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QObject>
#include <QTcpSocket>
#include <QTimer>
#include <QThread>
#include <filesystem>
#include <fstream>

class tcpClient : public QThread
{
    Q_OBJECT
public:
    tcpClient(QObject *parent=nullptr);
    void setRun();
    void sendData(std::string s);
    QTcpSocket *tcpSocket = nullptr;

public slots:   
    void connectServer(QString&, int&);

    void disConnectServer();


signals:
    void sendTcpMsg(const QString&);


private:
    void run();
    bool m_run;
};

#endif // TCPCLIENT_H

tcpClient.cpp

#include "tcpclient.h"


tcpClient::tcpClient(QObject *parent):
    QThread(parent)
{
    m_run = true;
    tcpSocket = new QTcpSocket(this);

}

void tcpClient::setRun()
{
    m_run = false;
}

void tcpClient::run()
{
    while(m_run)
    {
        if(tcpSocket->state() == QAbstractSocket::ConnectedState)
        {
            QString msg = tcpSocket->readLine();
            if(!msg.isEmpty())
            {
                emit sendTcpMsg(msg);
            }
        }
        msleep(200);
    }
    quit();
}

void tcpClient::sendData(std::string s)
{
    if(tcpSocket->state() == QAbstractSocket::ConnectedState)
    {
        tcpSocket->write(s.c_str());
    }
}

void tcpClient::connectServer(QString& ip, int& port)
{
    if(tcpSocket->objectName() == sender()->objectName())
        tcpSocket->connectToHost(ip, port);
}

void tcpClient::disConnectServer()
{
    if(tcpSocket->objectName() == sender()->objectName())
        tcpSocket->disconnectFromHost();
}

通过上面的试验可知:

1、槽函数的执行顺序和信号槽连接的顺序一致

2、首先利用 QObject::setObjectName(const QString&) 方法设置信号发出者的对象名称, 然后在槽函数中利用 QObject::sender()->objectName() 方法获取信号发出者的对象名称。

如需要源代码的话可私信本人,免费

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Qt中的信号机制是一种非常强大和灵活的通信机制,可以用于在对象之间传递信息。通过信号机制,可以实现对象之间的松耦合,并且能够传递任意类型的参数。 在Qt中,信号可以传递两个或更多的参数。当信号被触发时,可以通过传递参数来传递额外的信息。例如,我们可以定义一个带有两个参数的信号,并在某个特定条件下触发该信号。当信号被发射时,可以将两个参数的数值传递给与之相连的函数。 为了传递两个参数,我们需要在信号函数的声明中使用相应的参数类型。例如,我们可以在信号的声明中使用int和QString类型的参数,如下所示: signals: void mySignal(int arg1, QString arg2); 在函数的定义中,我们也需要使用相应的参数类型来接收对应的参数值。例如,我们可以定义一个函数来处理带有两个参数的信号: public slots: void mySlot(int arg1, QString arg2) { // 处理传递过来的两个参数 } 连接信号函数时,我们可以使用QObject::connect函数将信号函数绑定在一起。例如,我们可以这样连接信号: QObject::connect(sender, SIGNAL(mySignal(int, QString)), receiver, SLOT(mySlot(int, QString))); 在这个示例中,当sender对象触发mySignal信号时,mySlot函数将被调用,并传递信号的两个参数值。 总结起来,Qt信号机制可以方便地传递两个或更多的参数,只需在信号函数的声明中使用相应的参数类型即可。通过信号机制,可以实现对象之间的灵活通信,并且能够传递任意类型的参数。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值