coding
unsky
deepdim
thought

QT5从入门到放弃:(4)窗口通讯初步

信号和槽的机制简单理解就是,做一件事,发射一种信号,然后执行槽内的程序。

QT可以手动设置信号与槽也可以自动设置,为了了解最基本的原理我们从最基本的手动设置开始:

手动实现信号与槽


如图在设计师模块中加入push button 并将其objectName 设置为showChild.
下面开始使用这个push button.

首先明确我们的目的师设计按下push button之后产生信号,信号激活槽内的程序使其产生一个label的窗口。

首先我们需要先声明槽(slots).
note:

1
2
c++编程补充:因为c++需要声明和定义,一般都将声明写进 .h文件,而定义写在.cpp文件中。
在程序的书写中不需要包含各种cpp文件,程序在执行中动态的调用各种函数。

所以我们先在mainwindow.h声明槽

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#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();
public slots:
void showChild();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

其中

1
2
public slots:
void showChild();

声明了槽函数 showChild();
在声明完之后我们需要给其具体的定义,在mainwindow.cpp中进行定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->showChildButton,SIGNAL(clicked()),this,SLOT(showChild()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showChild()
{ QLabel *label=new QLabel();
label->setText("I AM SLOT!");
label->show();
}

因为我们在mainwindow.h中定义了类的名字空间

1
2
3
namespace Ui {
class MainWindow;
}

所以这里函数的具体定义我们应该写成:

1
2
3
4
5
6
7
void MainWindow::showChild()
{ QLabel *label=new QLabel();
label->setText("I AM SLOT!");
label->show();
}

在定义完之后。我们需要进行具体的连接,也就是将信号和槽进行连接,我们在类的构造函数内完成,

1
connect(ui->showChildButton,SIGNAL(clicked()),this,SLOT(showChild()));

connect的第一个参数是发送信号的对象,第二个是信号,第三个是接受信号的对象,第四个是槽函数。
这是手工的做法

自动信号与槽

我们现在简单的实现一个登陆界面和主界面的切换程序。

从最开始开始。新建一个空的项目。

在工程文件里加上QT + =widgets

新建第一个登陆界面:

新建一个空的QT设计师
选择Dialog without buttons
类名就写 myDialog

点F4进入信号与槽模式
先设计退出按钮,左键点击退出按钮的下边然后拉到主窗口的边缘,意思也就是信号源是退出按钮,接受源是整个窗口。

设计成功后的样子:

然后再设计进入主程序:
F3回到设计模式,右键点击进入主程序按钮,选择转到槽,然后选择click(),之后点击确定。

这时候转到了myDialog类的源文件即 myDialog.cpp加入代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "mydialog.h"
#include "ui_mydialog.h"
myDialog::myDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::myDialog)
{
ui->setupUi(this);
}
myDialog::~myDialog()
{
delete ui;
}
void myDialog::on_pushButton_clicked()
{
accept();
}

其中on_pushButton_clicked(),其声明在myDialog里也被自动声明完了,就是上面我们所说的实现模式就是自动生成函数
我们在里面加入:
1
2
3
4
void myDialog::on_pushButton_clicked()
{
accept();
}

accept()这个函数的作用就是判断哪个是主程序界面这个按钮被按下,如果被按下则返回QDialog::Accepted.

设计第二个界面

第二个界面有:

重新登陆按钮的设计:

和前面一样,右键转到槽

1
2
3
4
5
6
7
void myDialog1::on_pushButton_clicked()
{
close();
myDialog win;
win.show();
}

即关闭之后重新建立一个myDialog窗口。

退出按钮

和前面的退出按钮设计相同。

显示label按钮

右键转到槽
加入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void myDialog1::on_pushButton_2_clicked()
{
QLabel *label=new QLabel(this);
label->setText("uhgiuhuh");
label->show();
}
至此没有Dialog.cpp变为
```cpp
#include <QLabel>
#include "mydialog1.h"
#include "ui_mydialog1.h"
#include "mydialog.h"
myDialog1::myDialog1(QWidget *parent) :
QDialog(parent),
ui(new Ui::myDialog1)
{
ui->setupUi(this);
}
myDialog1::~myDialog1()
{
delete ui;
}
void myDialog1::on_pushButton_clicked()
{
accept();
}
void myDialog1::on_pushButton_2_clicked()
{
QLabel *label=new QLabel(this);
label->setText("uhgiuhuh");
label->show();
}

主程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<QApplication>
#include"mydialog.h"
#include"mydialog1.h"
int main(int argc,char *argv[])
{ QApplication w(argc,argv);
myDialog win1;
myDialog1 win2;
if(win1.exec()==QDialog::Accepted)
{ if(win2.exec()==QDialog::Accepted)
{ win1.show();
return w.exec();
}
}
else return 0;
}

即如果第一界面的进入主程序被按下,执行

1
2
3
4
if(win2.exec()==QDialog::Accepted)
{ win1.show();
return w.exec();
}

这句语句的意思是如果第二个窗口的重新登陆被按下则显示第一个界面。

坚持原创技术分享,您的支持将鼓励我继续创作!