目录

一、QWidget类(重点)

二、子组件(掌握)

三、样式表(熟悉)

一、什么是信号槽?

二、信号槽的连接方式

2.1 自带信号→自带槽

2.2 自带信号→自定义槽

2.3 自定义信号

三、传参方式

3.1 成员变量

3.2 静态局部变量

3.3 信号槽传参

四、对应关系

4.1 一对多

4.2 多对一


一、QWidget类(重点)

QWidget类是Qt中所有可视化组件和窗口的基类,其内部规定了很多成员,这些成员都会继承给其派生类。

常用成员,所有属性的Access functions对应的都是封装后的接口,即getter和setter:

  • width : const int

宽度

  • height : const int

高度

宽高无法直接设定,可以通过resize函数一起改变。

  • x : const int

x轴坐标,x轴的正方向向右

  • y : const int

y轴坐标,y轴的正方向向下,原点在左上。

坐标无法直接设定,可以通过move函数一起改变,任何组件和窗口的定位点是左上角。位置是相对的,取决于当前组件或窗口属于什么。

  • void QWidget::show() [slot]

展示

  • void setGeometry(int x, int y, int w, int h)

同时设置坐标与宽高。

二、子组件(掌握)

窗口中要有其它的子组件,不然只是空内容的窗口。

使用QPushButton类作为子组件,QPushButton表示一个按钮,构造函数如下

QPushButton(const QString & text, QWidget * parent = 0)

参数一:显示文本,QString是Qt中的字符串类。

参数二:父窗口或父组件

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
// 引入头文件
#include <QPushButton>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton *btn;
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    // 改变宽高(不包含标题栏)
    resize(200,200);
    // 移动位置
    move(200,200);
    // 创建按钮对象
    // this指的是主函数中的Dialog w对象
    // this结合多态进行参数传递
    btn = new QPushButton("你好",this);
    btn->resize(50,50);
    // 相对坐标
    btn->move(50,50);
    // 展示
    btn->show();
}Dialog::~Dialog()
{    // C++:有new就有delete
    delete btn;
}

三、样式表(熟悉)

默认的组件样式比较普通,可以通过设置样式表来自定义组件样式。

void setStyleSheet(const QString & styleSheet)

参数为QSS语法的样式,QSS语法类似于CSS。

配色网站:在线颜色选择器 | RGB颜色查询对照表

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
// 引入头文件
#include <QPushButton>
// 预设样式
#define QPushButton_STYTLE (QString("\
/*按钮普通态*/\
QPushButton\
{\
    font-family:Microsoft Yahei;\
    /*字体大小为20点*/\
    font-size:20pt;\
    /*字体颜色为白色*/\
    color:white;\
    /*背景颜色*/\
    background-color:rgb(188, 238, 104);\
    /*边框圆角半径为8像素*/\
    border-radius:8px;\
}\
/*按钮悬停态*/\
QPushButton:hover\
{\
    /*背景颜色*/\
    background-color:rgb(100 , 137 , 255);\
}\
/*按钮按下态*/\
QPushButton:pressed\
{\
    /*背景颜色*/\
    background-color:rgb(14 , 135 , 10);\
    /*左内边距为3像素,让按下时字向右移动3像素*/\
    padding-left:3px;\
    /*上内边距为3像素,让按下时字向下移动3像素*/\
    padding-top:3px;\
    /*字体颜色为白色*/\
    color:black;\
}"))class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton *btn;
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    // 同时设置x,y,宽,高
    setGeometry(200,200,200,200);    btn = new QPushButton("你好",this);
    btn->setGeometry(50,50,100,100);
    // 给按钮设置样式表
//    btn->setStyleSheet("background-color:green;color:red");
    btn->setStyleSheet(QPushButton_STYTLE);
    // 展示
    btn->show();
}Dialog::~Dialog()
{    // C++:有new就有delete
    delete btn;
}

Tip:

在Qt程序运行过程中,如果出现

表示当前程序已经运行,需要先关闭已经运行的程序,再重新运行。

一、什么是信号槽?

之前写的代码,只能看,不能交互。使用信号槽可以让用户与图形用户界面进行人机交互,信号槽是Qt特有的一种组件对象之间的通信机制。

信号函数是一种特殊的函数,槽函数也是一种特殊的函数。

使用信号槽进行组件对象之间的通信有两个前提条件:

1. 通信的对象必须是中QObject派生出来的,QObject类是所有Qt类型的基类。

2. 类中要有Q_OBJECT宏。

信号槽的使用主要通过下面的连接函数:

参数1:发射者,即触发动作的、作为条件的组件对象,通常是名词(对象名称)。

参数2:信号函数的名称,使用SIGNAL()包裹,信号函数是作为条件的动作本身,通常是 动词(函数名称)。信号函数一定属于发射者。

参数3:接收者,作为执行结果动作的对象,通常是名词(对象名称)。

参数4:槽函数的名称,使用SLOT()包裹,作为结果执行的具体动作,通常是动词(函数 名称)。槽函数是一种特殊的成员函数。槽函数一定属于接收者。

整个信号槽的连接,可以总结为:

receiver绑定了sender的signal信号,一旦sender发出signal信号,receiver就执行method函数。

信号槽的断开连接方式有两种:

  • 当发射者或接收者对象销毁时,信号槽连接自动断开
  • 调用disconnect函数手动断开信号槽连接,参数与connect函数一样。

二、信号槽的连接方式

为了方便渐进式的学习,信号槽连接依次讲解以下几种方式:

  • 自带信号→自带槽
  • 自带信号→自定义槽
  • 自定义信号→槽函数(自带或自定义皆可)

2.1 自带信号→自带槽

这是最简单的一种连接方式,因为信号函数与槽函数都是Qt内置的函数,程序员只需要找到对应的关系调用connect函数连接即可。

【例子】点击按钮,关闭窗口。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton* btn;
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(300,300);
    btn = new QPushButton("关闭",this);
    btn->move(150,150);
    // 连接信号槽
    // 参数1:发射者,按钮
    // 参数2:信号函数,clicked()
    // 参数3:接收者,窗口
    // 参数4:槽函数,close()
    connect(btn,SIGNAL(clicked()),this,SLOT(close()));
}Dialog::~Dialog()
{    delete btn;
}

2.2 自带信号→自定义槽

即使Qt内置的函数再多,也总有触及不到的需求,对于一些没有内置的槽函数,就需要程序员手动去编写了。

【例子】点击按钮,窗口向右下方移动 10*根2 个像素,并输出移动后的窗口坐标。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>
#include <QDebug>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton* btn;    // 1. 声明槽函数
private slots:
    void mySlot();
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(300,300);
    btn = new QPushButton("向右下",this);
    btn->move(140,140);
    // 连接信号槽
    // 点击按钮,执行自定义槽函数
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
}// 2. 定义槽函数
/**
 * 窗口向右下方移动14.1个像素,并输出移动后的窗口坐标。
 */
void Dialog::mySlot()
{    // 获取窗口的当前坐标
    int x = this->x();
    int y = this->y();
    // 移动窗口
    move(x+10,y+10);
    // 打印新坐标
    qDebug() << x+10 << "*" << y+10;
}Dialog::~Dialog()
{    delete btn;
}

2.3 自定义信号

这种方式主要用在后面一些特定的时机,现在只是为了讲解强行使用。

信号函数具有以下特点:

  • 信号函数只有声明,没有定义
  • 信号函数无需调用,只需发射
  • 信号函数的参数使用哑元
  • 信号函数无权限

【例子】点击按钮,关闭窗口。

这一次把上面的动作分解为:

点击按钮,调用自定义槽函数,在自定义槽函数中发射自定义信号;

自定义信号触发关闭窗口的动作。

与之前的对比如下:

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton* btn;// 声明自定义槽函数
private slots:
    void mySlot();// 声明自定义信号
signals:
    void mySignal();
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(200,200);
    btn = new QPushButton("关闭",this);
    btn->move(80,80);    // 连接信号槽
    connect(btn,SIGNAL(clicked()),this,SLOT(mySlot()));
    connect(this,SIGNAL(mySignal()),this,SLOT(close()));
}void Dialog::mySlot()
{    // 发射自定义信号
    emit mySignal();
}Dialog::~Dialog()
{    delete btn;
}

三、传参方式

【例子】有一个按钮,按钮上显示按钮点击的次数。

需要用到整型转字符串函数

QString number(int n, int base = 10) [static]

参数1:要转换的数字

参数2:进制

返回值:转换后的字符串

3.1 成员变量

代码与3.2合并。

3.2 静态局部变量

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    int count1 = 0; // 按钮1的点击次数    QPushButton* btn1;
    QPushButton* btn2;private slots:
    // 两个按钮点击的槽函数
    void btn1ClickedSlot();
    void btn2ClickedSlot();
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(300,300);
    btn1 = new QPushButton("0",this);
    btn1->move(150,150);
    btn2 = new QPushButton("0",this);
    btn2->move(150,180);    // 连接信号槽
    connect(btn1,SIGNAL(clicked()),this,SLOT(btn1ClickedSlot()));
    connect(btn2,SIGNAL(clicked()),this,SLOT(btn2ClickedSlot()));
}void Dialog::btn1ClickedSlot()
{    count1++; // 计数+1
    // 把整型转换为字符串
    QString text = QString::number(count1);
    // 设置到按钮上
    btn1->setText(text);
}void Dialog::btn2ClickedSlot()
{    static int count2 = 0;
    count2++;
    QString text = QString::number(count2);
    btn2->setText(text);
}Dialog::~Dialog()
{    delete btn1;
    delete btn2;
}

3.3 信号槽传参

为了讲解信号槽传参,强行在上面的例子中使用。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton* btn;
    int count = 0;private slots:
    void btnClickedSlot();
    // 带参数的槽函数,来接收信号发送的参数
    void mySlot(int);signals:
    // 带参数的信号函数
    void mySignal(int);
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(300,300);
    btn = new QPushButton("0",this);
    btn->move(50,50);    connect(btn,SIGNAL(clicked()),this,SLOT(btnClickedSlot()));
    connect(this,SIGNAL(mySignal(int)),this,SLOT(mySlot(int)));
}void Dialog::btnClickedSlot()
{    count++;
    // 发射带参数的自定义信号
    emit mySignal(count);
}/**
 * @brief Dialog::mySlot
 * @param count 信号发射过来的
 */
void Dialog::mySlot(int count)
{    QString text = QString::number(count);
    btn->setText(text);
}Dialog::~Dialog()
{    delete btn;
}

信号槽传参需要注意:

1. 理论上可以传递任意多个参数,但通常传递1-2个参数。

2. 信号的参数个数必须大于等于槽的参数个数。

3. 参数的类型需要一一匹配。

四、对应关系

4.1 一对多

同一个信号可以同时链接到多个槽。

一对多的情况也可以优化为下面的代码:

4.2 多对一

多个信号也可以同时连接到同一个槽。

dialog.h

#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QPushButton>
#include <QDebug>class Dialog : public QDialog
{    Q_OBJECTpublic:
    Dialog(QWidget *parent = 0);
    ~Dialog();private:
    QPushButton* btn1;
    QPushButton* btn2;private slots:
    void mySlot1();
    void mySlot2();
};#endif // DIALOG_H

dialog.cpp

#include "dialog.h"Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
{    resize(200,200);
    btn1 = new QPushButton("按钮1",this);
    btn2 = new QPushButton("按钮2",this);
    btn1->move(50,50);
    btn2->move(50,80);
    // 一对多
    //    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot1()));
    //    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot2()));
    // 多对一
    connect(btn1,SIGNAL(clicked()),this,SLOT(mySlot1()));
    connect(btn2,SIGNAL(clicked()),this,SLOT(mySlot1()));
}void Dialog::mySlot1()
{    qDebug() << "槽函数1";
}void Dialog::mySlot2()
{    qDebug() << "槽函数2";
}Dialog::~Dialog()
{    delete btn1;
    delete btn2;
}

QT入门-UI-信号槽相关推荐

  1. Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用)

    Qt线程间信号槽传递自定义数据类型(qRegisterMetaType的使用) #include <QMetaType> CFileDataModel::CFileDataModel(QO ...

  2. QT C++ 《信号-槽 基本操作》

    目录 <信号-槽 基本操作> 信号-槽连接 信号-槽断开连接 信号-槽连接 connect(ui.pushButton_SIGNAL, SIGNAL(clicked()), Client_ ...

  3. QT:PushButton+信号槽+Label简单使用

    实现内容 创建一个简单的QT GUI项目,实现点击按钮修改Label的内容 创建QT GUI 项目:ButtonTest 创建后的目录为: 添加界面布局 在界面添加两个PushButton和一个Lab ...

  4. Qt / Moc 和信号 - 槽解析

    目录 一. MOC 二. moc_test.cpp 分析 三. connect 四. activate 五. 总结 版本 Qt5.12.3 moc_test.cpp 位于可执行文件目录下,其余源代码都 ...

  5. Qt学习笔记-----信号槽

    Qt提供signals and slots mechanism(信号槽机制)来保证两个对象之前的关联(connection). 所谓信号槽,简单理解就是两部分,一个是某对象发出的信号,一个是某对象接收 ...

  6. Qt中绑定信号槽之后,信号槽无效

    下面程序编译没有错误,运行却未达到想要的效果,最后调试发现,是信号槽绑定后无效,即槽函数没有受到信号的触发.具体代码如下: main.cpp #include <QtCore> #incl ...

  7. Qt多线程间信号槽传递非QObject类型对象的参数

    一.以前就发现过这个问题: 在Qt项目中,有时候为了让自己的类,可以重载操作符 '=','<<','>>'. 也有时候需要用一个类进行文件的读写,所以很多C++类还是要简单化的 ...

  8. 玩转Qt(6)-认清信号槽的本质

    简介 猫和老鼠的故事 对象之间的通信机制 尝试一:直接调用 尝试二:回调函数+映射表 观察者模式 Qt的信号-槽 信号-槽简介 信号-槽分两种 信号-槽的实现 元对象编译器moc moc的本质-反射 ...

  9. qt 多线程、信号槽、moveToThread等机制之拨乱反正

    之所以要"拨乱反正",是因为很多教科书上的说法,还有网页上的说法,都是错误的. 我没有看过qt源码,看过一些书籍,做过一些实验,说下我的理解.如有谬误,还请讨论. 首先来看看教科书 ...

最新文章

  1. cocos2d-x中几种存储数据的方式
  2. Ubuntu报错记录(Could not get lock /var/lib/dpkg/lock-frontend问题的解决方法)
  3. (JAVA学习笔记) 类的继承,super,方法的重写,多态
  4. html label修改字体颜色,Swift label文字显示不同颜色(字体)
  5. 用Spark学习FP Tree算法和PrefixSpan算法
  6. Html去掉链接虚线边框
  7. abap 取日期最大_Pointer干货分享:SQL面试50题思路解答与分类整理(下)CASE与日期函数...
  8. Android报加密错误,在android中解密使用aes/gcm/nopadding加密的消息时出错
  9. git全局配置用户名和密码_git---全局设置用户名、密码、邮箱
  10. azure vnc控制台_使用扩展和标签控制Azure成本
  11. php 保存错误日志,PHP中把错误日志保存在系统日志中_PHP教程
  12. android添加工程依赖工程,将项目依赖项添加到Android studio中的另一个项目
  13. chmod ug s oracle,Linux chmod设置目录和文件不同权限
  14. Linux运维04:vmstat命令详解
  15. 软件工程,java开发网上购物系统,数据流图DFD图,用例图
  16. 李智慧 - 架构师训练营 第五周
  17. 你与顶级UI设计师的区别在哪里
  18. Linux-打包、压缩命令
  19. StudyNotes_MachineLearning_3(吴恩达机器学习公开课)
  20. JVM运行时内存结构学习

热门文章

  1. mysql8.0.28下载安装教程(win10),一键安装,超详细
  2. java表单验证手机号码位数,jquery验证手机号码和邮箱地址例子
  3. Unity从零开始制作飞机大战
  4. 数字图像处理-Digital Image Processing(DIP)--5图像的平滑处理
  5. java getmethod 使用_java – 使用子类作为方法参数调用getMethod
  6. hive误删数据表恢复
  7. ElementUI 引入Jquery
  8. 开发框架-SpringMVC
  9. Vue - 超详细 Element 组件库主题颜色进行 “统一全局“ 替换,将默认的蓝色主题色更换为其他自定义颜色(保姆级教程,简易且标准全局替换主题色)
  10. SQL MINUS