QT简单入门实例8【信号槽的新建,连接,触发】

1 UI控件的信号槽(以QPushButton为例)

QT的各种UI控件(例如按钮,滑动条,标签等),都有很多信号,这些信号在控件状态变化时(比如鼠标按下的时候)信号会自动触发
在“按钮”控件上鼠标右击可以转到槽,可以看到,QPushButton类总共有12个不同的信号,分别继承自QAbstractButton, QObject, Qwidget。
最常用的就是:
clicked() —— 鼠标左键松开时触发一次
pressed() —— 鼠标左键按下时触发一次
在这里插入图片描述
点击ok可以转到该按钮的clicked槽函数,在该按钮的clicked信号触发时(即鼠标点击该按钮并松开的瞬间),程序会跳转到该槽函数,执行其中的代码

// ui->pushButton 的槽函数
void MainWindow::on_pushButton_clicked() 
{
    //... Code executed when the button is clicked  
}

总结:

新建:UI控件的信号无须创建;槽使用 “右键转到槽” 的方法即可新建。
连接:将槽函数命名为:on_控件名_信号名 ,信号会自动连接到槽,无须手动进行连接。
触发:当控件状态改变时信号就会自动触发,因为已经进行了信号槽连接,所以槽的代码就会自动执行。

2 自定义的信号槽(以两个类之间传递信号为例)

注意:如果想在两个类之间使用信号槽传递信号,必要条件是这两个类都直接或间接继承自QObject类,并且在类中声明宏 Q_OBJECT。

实现效果:

点击按钮后,MyClass类会发送一个带参信号给Mainwindow类,这个参数类型是QString,Mainwindow类收到信号后将参数内容打印出来。
在这里插入图片描述

代码如下:

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_pushButton_clicked();
    void myslot(QString); //定义私有槽

private:
    Ui::MainWindow *ui;
};

//公有继承自 QObject
class MyClass : public QObject
{
    Q_OBJECT //声明宏,为了可以使用信号槽机制
public:
    MyClass(){}
    ~MyClass(){}
signals:
    void mysignal(QString); //定义信号(信号全部是公有的)
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MyClass myclass; //MyClass实例化

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //信号槽连接
    this->connect(&myclass,SIGNAL(mysignal(QString)), \
                  this,SLOT(myslot(QString)),Qt::AutoConnection);
}

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

void MainWindow::on_pushButton_clicked()
{
    //触发信号(推荐在本类触发信号,这里只是为了演示目的)
    emit myclass.mysignal("这是一条来自myclass对象的信号");
}

//槽的实现
void MainWindow::myslot(QString str)
{
    qDebug()<<str;
}

3 三点说明

关于信号槽连接方式

单线程中,只需要 Qt::AutoConnection (默认连接),形如:

connect(&myclass,SIGNAL(mysignal(QString)), \
                  this,SLOT(myslot(QString)));
connect(&myclass,SIGNAL(mysignal(QString)), \
                  this,SLOT(myslot(QString)),Qt::AutoConnection);

关于一对多和多对一

一个信号连接多个槽时,槽函数的执行顺序:按连接的先后顺序执行
多个信号连接多个槽时,可在槽函数中判断信号的发出者

关于利用信号槽传递自定义类型(例如MyType)

为了能够在队列中存储自定义类型参数,Qt需要去construct、destruct、copy这些对象,而为了让Qt知道怎样去作这些事情,参数的类型需要使用qRegisterMetaType来注册,否则编译器会报错。

qRegisterMetaType <MyType> ("MyType"); //注册参数类型MyType
QObject::connect(pObject,SIGNAL(mysignal(MyType)),this,SLOT(mylot(MyType)));

关于多线程中信号槽的连接方式,一对多与多对一的具体例子,请看我之后的博文

发布了22 篇原创文章 · 获赞 8 · 访问量 9040

猜你喜欢

转载自blog.csdn.net/Sun_tian/article/details/104373255
今日推荐