QT:信号与槽

QT是一种流行的C++框架,用于开发图形用户界面(GUI)应用程序。在QT中,信号与槽是一种用于实现对象间通信的机制。

信号(signal)是对象发出的事件或消息,槽(slot)是接收并处理这些事件或消息的函数。当一个对象的信号被触发时,与之关联的槽函数将被调用。

使用信号与槽机制可以实现对象之间的解耦,使得对象间的通信更加灵活和可扩展。在使用信号与槽时,首先需要定义信号和槽函数,并将它们关联起来。然后,在适当的时候,通过调用emit关键字触发信号,从而调用与之关联的槽函数。

1.以下是一个简单的示例,演示了如何在QT4中connect中使用信号与槽:

// 定义一个自定义的类
class MyObject : public QObject
{
    Q_OBJECT  // 宏,用于启用信号与槽机制

public:
    MyObject() {}

    // 定义一个信号
    signals:
        void mySignal(int value);

    // 定义一个槽函数
    public slots:
         void mySlot(int value) {
             qDebug() << "Received value:" << value;
         }
};

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

    MyObject obj;

    // 将信号与槽函数关联起来
    QObject::connect(&obj, SIGNAL(mySignal(int)), &obj, SLOT(mySlot(int)));

    // 触发信号
    emit obj.mySignal(42);

    return app.exec();
}

在上述示例中,我们首先定义了一个自定义类MyObject,其中包含一个信号mySignal和一个槽函数mySlot。然后,我们使用QObject::connect函数将这两个成员关联起来。最后,在main函数中,我们触发了mySignal信号,从而调用mySlot槽函数,并打印出接收到的值。

需要注意的是,为了使用信号与槽机制,类必须包含Q_OBJECT宏,并且必须使用moc工具(QT的元对象编译器)对类进行预处理。在示例中,我们使用QApplication类来创建一个QT应用程序,并调用app.exec()来启动事件循环。

这只是一个简单的示例,QT的信号与槽机制还有更多的特性和用法。详细的使用方法和注意事项可以参考QT的官方文档。

2.qt5中connect连接

在Qt框架中,信号和槽是对象间通信的一种方式。信号是当某个事件发生时由对象发出的通知,而槽则是对这些事件的响应。`connect`函数用于将信号连接到槽,从而实现对象间的通信。

以下是使用`connect`函数连接信号和槽的基本步骤:

1. **定义信号和槽**:
   - 信号通常在类声明中定义,使用`signals`关键字。
   - 槽可以是任何成员函数,也可以是全局函数或静态成员函数。

2. **创建对象**:
   - 创建需要通信的对象实例。

3. **使用`connect`函数**:
   - 使用`connect`函数将信号连接到槽。

下面是一个简单的例子:
#include <QApplication>
#include <QPushButton>
#include <QDebug>

class MyClass : public QObject {
    Q_OBJECT

public:
    MyClass(QObject *parent = nullptr) : QObject(parent) {}

public slots:
    void mySlot() {
        qDebug() << "Slot called!";
    }
};

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

    MyClass myObject;
    QPushButton button;

    // 连接信号和槽
    QObject::connect(&button, &QPushButton::clicked, &myObject, &MyClass::mySlot);

    button.show();
    return app.exec();
}
```

在这个例子中:

- `QPushButton`有一个信号`clicked()`,当按钮被点击时发出。
- `MyClass`有一个槽`mySlot()`,当被调用时打印一条消息。
- 使用`QObject::connect`函数将`QPushButton`的`clicked`信号连接到`MyClass`的`mySlot`槽。

### `connect`函数的参数

`connect`函数的基本形式是:

```cpp
bool QObject::connect(const QObject *sender, const char *signal,
                      const QObject *receiver, const char *method,
                      Qt::ConnectionType type = Qt::AutoConnection);
```

- **sender**:发出信号的对象。
- **signal**:信号的名称,通常使用函数指针语法。
- **receiver**:接收信号的对象,即槽所在的对象。
- **method**:槽的名称。
- **type**:连接类型,可以是`Qt::AutoConnection`(默认),`Qt::DirectConnection`或`Qt::QueuedConnection`。

### 信号和槽的语法

信号和槽的声明使用函数指针语法:

- **信号**:`signals: void mySignal();`
- **槽**:`public slots: void mySlot();`

3.优化登录框:

当用户点击取消按钮,弹出问题对话框,询问是否要确定退出登录,并提供两个按钮,yes|No,如果用户点击的Yes,则关闭对话框,如果用户点击的No,则继续登录

当用户点击的登录按钮,进行账号和密码的匹配,如果匹配成功,则弹出信息对话框,给出信息为,登录成功,并给出一个确定按钮,当用户点击该按钮后,关闭登录界面,弹出另一个界面

当账号和密码不匹配是,给出错误对话框,给出信息为账号和密码不匹配,是否重新登录,并提供两个按钮 Yes|No,如果用户点击了Yes,则清空密码框后,继续登录。如果用户点击的取消,则关闭登录界面

#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{

    this->resize(800,600);
    this->setWindowTitle("QQ");
    this->setWindowIcon(QIcon(":/icon/QQ.png"));


    lab1=new QLabel(this);
    lab1->setPixmap(QPixmap(":/icon/R.jfif"));
    lab1->resize(800,250);

    lab2=new QLabel(this);
    lab2->setPixmap(QPixmap(":/icon/3.jpg"));
    lab2->move(150,350);
    lab2->resize(100,100);


    lab3=new QLabel(this);
    lab3->setText("账号:");
    lab3->resize(60,30);
    lab3->move(lab2->width()+lab2->x()+40,lab2->y());

    lab4=new QLabel(this);
    lab4->setText("密码:");
    lab4->resize(60,30);
    lab4->move(lab3->x(),lab3->y()+lab3->height()+30);

    edit1=new QLineEdit(this);
    edit1->resize(180,30);
    edit1->move(lab3->x()+lab3->width()+10,lab3->y());
    edit1->setStyleSheet("color:black");
    edit1->setAlignment(Qt::AlignLeft);
    edit1->setPlaceholderText("输入QQ账号");

    edit2=new QLineEdit(this);
    edit2->resize(180,30);
    edit2->move(lab4->x()+lab4->width()+10,lab4->y());
    edit2->setStyleSheet("color:black");
    edit2->setAlignment(Qt::AlignLeft);
    edit2->setEchoMode(QLineEdit::Password);
    edit2->setPlaceholderText("输入QQ密码");

    btn1=new QPushButton(this);
    btn1->setText("登录");
    btn1->resize(80,40);
    btn1->setIcon(QIcon(":/icon/登录.png"));


    btn1->move(lab4->x()+20,lab4->y()+lab4->height()+40);

    btn2=new QPushButton(this);
    btn2->setText("取消");
    btn2->resize(btn1->size());
    btn2->move(btn1->x()+btn1->width()+60,btn1->y());
    btn2->setIcon(QIcon(":/icon/退出登录.png"));

    QObject::connect(this->btn2,&QPushButton::clicked,this,&Widget::cancel_slot);

    QObject::connect(btn1,&QPushButton::clicked,this,&Widget::login_slot);


}

Widget::~Widget()
{
}

void Widget::login_slot()
{
    if(edit1->text()==edit2->text())
    {

        QMessageBox box(QMessageBox::Information,"登录","登录成功",QMessageBox::Yes,this);

        box.setButtonText(QMessageBox::Yes,"确认");

        int btn1=box.exec();
        if(btn1==QMessageBox::Yes)
        {
            this->close();
            emit jump();
        }

    }
    else
    {
        int err=QMessageBox::critical(this,"","账户或密码错误,是否重新登录",
                                      QMessageBox::Yes | QMessageBox::No,
                                      QMessageBox::Yes);
        if(err==QMessageBox::Yes)
        {
            this->edit2->clear();
        }else if(err==QMessageBox::No)
        {
            this->close();
        }

    }

}

void Widget::cancel_slot()
{
    QMessageBox box(QMessageBox::Question,"取消","是否取消登录",
                    QMessageBox::Yes | QMessageBox::No,this);

    box.setButtonText(QMessageBox::Yes,"是");
    box.setButtonText(QMessageBox::No,"否");

    int btn2=box.exec();
    if(btn2==QMessageBox::Yes)
    {
        this->close();
    }else if(btn2==QMessageBox::No)
    {

    }
}

weight.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPushButton>
#include <QLineEdit>
#include <QLabel>
#include <QDebug>
#include <QMessageBox>

class Widget : public QWidget
{
    Q_OBJECT

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

private:
    QLabel *lab1;
    QLabel *lab2;
    QLabel *lab3;
    QLabel *lab4;

    QLineEdit *edit1;
    QLineEdit *edit2;

    QPushButton *btn1;
    QPushButton *btn2;

public slots:
    void login_slot();
    void cancel_slot();

signals:
    void jump();
};
#endif // WIDGET_H

上一篇:横向移动与痕迹清理-痕迹清除


下一篇:等级保护测评实战:构建坚不可摧的网络安全防线