一 Qt 基本概念
1. 基本介绍及环境的配置


(1)测试安装是否成功
- 文件->新建文件或项目->Application->Qt Widgets Application ->chooose


- 然后一直点下一步即可,直到出现完成,确定之后,会出现如下界面,然后点击左下角的小锤子,左下角的三个标会变成灰色,等再次变成彩色之后,点击左下角的三角形开始图标,远离锤子的彩色三角形开始图标
- 运行之后出现一个弹窗表示软件安装成功


(2)设置编译路径(可做可不做)

- 参照红色圈所示进行设置,这是避免最后文件路径过长


- 添加Qt源码选择的路径是QT安装路径下的Src路径,源码路径就会更新,点击ok即可

(3)创建快捷方式
- 找到安装目录下的如下文件目录
F:\QT\install_file\Tools\QtCreator\bin,找到如下图标,右键选择”发送到“桌面快捷方式即可 
(4)创建新项目


默认即可


二 基本概念
1. 基本介绍
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec(); //a.exec()进入事件循环
}
a.exec()途中的循环图标表示,不断的对待运行的程序进行执行

- 主要类之间的继承关系
)


- 用
QT_BEGIN_NAMESPACE和QT_END_NAMESPACE表示声明指定内容为所有地方可用,相当于定义命名空间

2. 基本介绍
2.1 信号槽
- 基本概念:完成对象之间的通信


2.2.1 信号与槽的关联实现方式1: 实现滚动条和text按键的关联,滑动滚动条text中对应的数字发生改变,也即滑动条是信号的发送者,text按键是信号的接收者,常规来说,实现信号与槽的关联之后,还要发送信号,当前案例在滑动滚动条的时候,会自动发送信号,因此当前案例没有手动发送信号的过程。在mainWindow.cpp文件的构造函数中实现信号与槽的关联


2.2.2 信号与槽的关联实现方式2:
- 实现text和label的关联
- 不写完整的参数列表,但是如果槽存在重载的情况,就无法正常运行,因为不指定传入的参数类型
QLabel::connect(ui->lineEditTest,
&QLineEdit::textChanged,
ui->label,
&QLabel::setText);

2.2.3 信号与槽的关联 以下案例,在注册按钮的槽中进行了相应信息的打印,但是并没有对文本框和注册按钮进行connect关联,为什么能获取到text中的信息,
- 知识点:通过
on_pushButton_clicked进行关联的,信号发送者pushButton,信号名称clicked,QT会根据slots进行命名解析,也即QT的自动关联是通过函数命名来实现的
void MainWindow::on_pushButton_clicked()
{
QString ret = ui->lineEditName->text() + ui->lineEditAge->text() + ui->lineEditJob->text() +
",欢迎注册";
QMessageBox::information(this, "Welcome", ret,QMessageBox::Ok);
}

- 为了进一步理解上述所说的根据函数名字来解析的,此处通过自定义一个函数,来实现控件之间的自动关联,
step1:确认发送信号的按键,以及槽函数,下列红色圈所示按键为发送信号的按键,按键名字lineEditTest,lineEdit按键对应的文本值发生改变的槽函数是textChanged,通过在程序中任意位置打印ui->lineEditTest,ctrl+鼠标右键单间lineEditTest跳转到按键对应的类声明中,查看对应的槽函数是textChanged的传入参数,const QString &


step2:在下列位置定义on_信号发射函数按键名_槽函数名(槽函数形参),然后在对应的MainWindow.cpp函数中实现,此处是一个测试
#include "QDebug"
void MainWindow::on_lineEditTest_textChanged(const QString & str){
qDebug() << "收到信号";
ui->label->setText(str);
}

step3:效果展示,每输入一个数字,输出控制台就实现了输出,说明在没有使用connect的情况下,实现了函数和文本框的关联

2.2 如何定义自己的信号,只有自己写的类才需要定义自己的信号,如果调用上述的已有的组件,是不需要自己来写信号的
- 知识点:信号知识一个空函数

2.3 自定义槽
- QT的组件会自动发送信号

- 通过手动发射信号方式,和界面上直接单击按钮是一样的效果,下面案例,通过点击
pushButton按钮,在按钮中发射信号,完成pushButtonTest按钮的单击操作,emit ui->pushButtonTest->clicked(); //和界面上单击是一样的效果,组件之间是自动调用的

通过点击A,实现B的调用

2.2 信号与槽的之间的关联

2.3 信号与槽的之间连接方式


- 阻塞队列连接:接收者按照自己的顺序处理,不受干扰,发送者等待接收者将前面信号处理完毕之后,处理当前发送者的信号




2.4 信号与槽的对应关系


- 程序量大的情况下,可能会在多个地方创建同样的多次链连接,可以使用
disconnect进行断开,
connect(btn, &QPushButton::clicked, this, &MainWindow::mySlot);
connect(btn, SIGNAL(clicked()), this, SLOT(mySlot()));
断开:
disconnect(btn, &QPushButton::clicked, this, &MainWindow::mySlot);
disconnect(btn, SIGNAL(clicked()), this, SLOT(mySlot()));
disconnect(btn,0,0)表示所有的连接都断开
2.5 信号槽如何传递自定义的参数类型
-
知识点1:自定义信号槽的参数类型,需要在连接前使用
qRegisterMetaType<Student>("Student");进行注册 -
知识点2:下面案例为什么要连接两次
我的理解:由于自定了按键,得先完成信号的发送,也即如果是自定义的组件,会自动发送信号,但是此处是我们自定义的按键,就需要手动发送信号,所以在mySlotButton中使用了emit发送信号,然后再次用connect发送信号以及接收信号
正确理解:跟自定义按键没关系,那个按钮的clicked信号没有参数为Student的,不能直接连接到mySlotRecieveStduent(student)
connect(btn, SIGNAL(clicked()), this, SLOT(mySlotButton()));
connect(this, SIGNAL(mySingnal(Student)), this, SLOT(mySlotRecieveStduent(Student)));
- 知识点3:信号是不需要实现的空函数

struct Student{
int age;
int score;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void mySlotButton(); //控制按钮
void mySlotRecieveStduent(Student std); //接收学生信息
signals:
void mySingnal(Student std);
private:
QPushButton *btn;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//用代码创建一个按钮
btn = new QPushButton(this);
//设置按钮的位置
btn->setGeometry(100,50, //原点在左上角,x,y坐标
80,40); //宽度和高度
btn->setText("我的按钮");
//connect(btn, &QPushButton::clicked, this, &MainWindow::mySlot);
qRegisterMetaType<Student>("Student");
connect(btn, SIGNAL(clicked()), this, SLOT(mySlotButton())); //连接按钮,使按钮发送信号
connect(this, SIGNAL(mySingnal(Student)), this, SLOT(mySlotRecieveStduent(Student)));
}
void MainWindow::mySlotButton(){
Student s;
s.age = 18;
s.score = 100;
emit mySingnal(s);
}
void MainWindow::mySlotRecieveStduent(Student std){
qDebug() << std.age << " " << std.score << endl;
}
3. 动态属性
3.1 概念–小案例,定义一个学生属性,并对其进行调用
-
和C++定义一个类,在类里面定义这个类的各种功能,是一个意思
-

-
知识点1:属性的定于方法,读和写是可选的,并不是一定要都定义,信号也是可选的,自定义组件是自动发射信号
//添加属性
//属性类型 属性类型 属性名 读方法 写方法 信号
Q_PROPERTY(QString love READ love WRITE setLove NOTIFY loveChange)
- 知识点2:属性的调用方法,三种方式
//使用属性
//1.使用C++传统
STU->setLove("sing");
//2.使用QT的动态属性
STU->setProperty("love", //属性名,必须是字符串
"play bastketball"); //
//3.通过父类对象指针来访问属性
QObject *obj = STU;
obj->setProperty("love", //属性名,必须是字符串
"eating"); //
- 知识点3:槽函数必须实现,否则会报错
- 知识点4:属性的定义和调用都麻烦,为什么还要使用Qt属性?Qt属性在调用的时候,可以只知道属性名,不需要知道其余的函数名称以及形参,方便使用者的调用
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
//添加属性
//属性类型 属性类型 属性名 读方法 写方法 信号
Q_PROPERTY(QString love READ love WRITE setLove NOTIFY loveChange)
public:
explicit Student(QObject *parent = nullptr);
QString love() const;
void setLove(QString strLove);
signals:
void loveChange(QString strLove);
private:
QString m_love;
};
#endif // STUDENT_H
----------------------------------------------------
#include "student.h"
Student::Student(QObject *parent) : QObject(parent)
{
}
QString Student::love() const
{
return m_love;
}
void Student::setLove(QString strLove)
{
m_love = strLove;
emit loveChange(strLove);
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void StuLoveChane(QString love);
private slots:
signals:
private:
Ui::MainWindow *ui;
QPushButton *btn;
};
#endif // MAINWINDOW_H
----------------------------------------------------
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QScrollBar"
#include "QLabel"
#include "QMessageBox"
#include "QDebug"
#include "student.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
Student *STU = new Student;
//窗口接收信号
connect(STU,SIGNAL(loveChange(QString)),this, SLOT(StuLoveChane(QString)));
//使用属性
//1.使用C++传统
STU->setLove("sing");
// qDebug() << STU->love();
//2.使用QT的动态属性
STU->setProperty("love", //属性名,必须是字符串
"play bastketball"); //

最低0.47元/天 解锁文章
6225






