—main.cpp如图所示,诸多的控件应该在主窗口中去实现而不应在主函数中实现
—改变编码
TOOLS—>options—>TextEditor—>behavor—>file coding 选择Utf-8—>apply—>OK
—设置控件
MainWdiget.h
private:
QPushButton b1;//对象
QPushButton *b2;//指针方式
QPushButton b3;
在MainWidget.cpp实现
b1.setParent(this);
b1.setText("close");
b1.move(100, 100);
b2 = new QPushButton(this);//注意指针需要动态分配空间,否则会发生段错误
b2->setText("abc");
至此可以在主窗口上显示两个按键
—实现点击b1就会关闭主窗口
如何查看一个类帮助文档:点击类名,按F1(按两次全屏显示帮助文档),如果没有发现signal,则去查看其基类(Inherits)的signals
b1.setParent(this);
b1.setText("close");
b1.move(100, 100);
connect(&b1, &QPushButton::pressed, this, &MainWidget::close);
/* &b1: 信号发出者,指针类型
* &QPushButton::pressed:处理的信号, &发送者的类名::信号名字
* this: 信号接收者
* &MainWidget::close: 槽函数,信号处理函数 &接收的类名::槽函数名字
*/
自定义槽的用法与普通函数的用法一样,Qt5中自定义槽可以是任意的成员函数,普通全局函数,静态函数。槽函数需要和信号一致(参数,返回值),信号是没有返回值的,故槽函数没有返回值
—通过点击b2将控件名字改变
connect(b2, &QPushButton::released, this, &MainWidget::mySlot);//b2是指针,不用取地址
写自定义槽函数时,一般写成共有的成员函数
MainWidget.h
void mySlot();//声明自定义槽函数
MainWidget.cpp
void MainWidget::mySlot()
{
b2->setText("123");
}
—通过点击抬起后b2使b1隐藏
MainWidget.cpp
connect(b2, &QPushButton::released, &b1, &QPushButton::hide);
—主窗口和 窗口切换
新建一个子窗口:
点击工程目录—>ADD NEW—>C++ CLASS—>命名为SubWidget基类选择为窗口类
添加一个按钮:在SubWidget.h中
private
QPushButton b;
SubWidget.cpp
this->setWindowTitle("son");
b.setParent(this);
b.setText("切换到主窗口");
在主窗口设置一个按钮
b3.setParent(this);
setWindowTitle("father");//this—>setWindowTitle("father")也可以
b3.setText("切换到子窗口");
b3.move(50, 50);
注意,在设置完该子窗口后RUN并不会显示两个独立窗口,应该将SubWidget.h包含到MainWidget.h中并定义一个对象w(private: SubWidget w;),然后在MainWidget.cpp中w.show()即可显示出两个独立窗口
MainWidget.h
public :
void changeWin();
MainWidget.cpp
connect(&b3, &QPushButton::released, this, &MainWidget::changeWin);
void MainWidget::changeWin()
{
//子窗口显示
subWin.show();
//本窗口隐藏
this->hide();
}
此时RUN,点击b3会显示子窗口w但是点击子窗口无反应,解决思路:在子窗口按下按钮后发出一个信号由主窗口处理
SubWidget.h
signals:
/* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 信号的使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
SubWidget.cpp
connect(&b, &QPushButton::clicked, this, &SubWidget::sendSlot);
void SubWidget::sendSlot()
{
emit mySignal();
}
MainWidget.cpp
connect(&w,&SubWidget::mySignal,this,&MainWidget::dealSub);
void MainWidget::dealSub()
{
//子窗口隐藏
subWin.hide();
//本窗口显示
show();
}
至此可以通过点击按钮实现两个窗口之间的切换
信号重载
函数指针
正确输出QString
SubWidget.cpp
//将mySignal()重载,产生一个带参信号
void SubWidget::sendSlot()
{
emit mySignal();
emit mySignal(250, "我是子窗口");//切换子窗口时打印内容
}
MMainWidget.h
//在头文件中声明
void dealSlot();
MainWidget.cpp
/*//之前也定义过一次,故会产生二义性,应该使用函数指针解决
connect(&w,&SubWidget::mySignal,this,&MainWidget::dealSub);
connect(&w,&SubWidget::mySignal,this,&MainWidget::dealSlot)*/
void (SubWidget::*funSignal)() = &SubWidget::mySignal;
connect(&subWin, funSignal, this, &MainWidget::dealSub);
void (SubWidget::*testSignal)(int, QString) = &SubWidget::mySignal;
connect(&subWin, testSignal, this, &MainWidget::dealSlot);
void MainWidget::dealSlot(int a, QString str)
{
// str.toUtf8() 转换成字节数组QByteArray
// ……data() 将 QByteArray 转换成 char *可以输出
qDebug() << a << str.toUtf8().data();
匿名函数对象
C++11新增加特性,需要在项目文件(.proc)加上 CONFIG += C++11
QPushButton *b4 = new QPushButton(this);
b4->setText("Lambda表达式");
b4->move(150, 150);
int a = 10, b = 100;
connect(b4, &QPushButton::clicked,
// = :把外部所有局部变量、类中所有成员以值传递方式,最常用
// this: 类中所有成员以值传递方式
// & : 把外部所有局部变量, 引用符号
[=](bool isCheck)
{
b4—>setText("123")
qDebug() << isCheck;
qDebug() << a<
MainWidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include
#include
#include "subwidget.h" //子窗口头文件
class MainWidget : public QWidget
{
Q_OBJECT
public:
MainWidget(QWidget *parent = 0);
~MainWidget();
public slots:
void mySlot();
void changeWin();
void dealSub();
void dealSlot(int, QString);
private:
QPushButton b1;
QPushButton *b2;
QPushButton b3;
SubWidget subWin;
};
#endif // MAINWIDGET_H
SubWidget.h
#ifndef SUBWIDGET_H
#define SUBWIDGET_H
#include
#include
class SubWidget : public QWidget
{
Q_OBJECT
public:
explicit SubWidget(QWidget *parent = 0);
void sendSlot();
signals:
/* 信号必须有signals关键字来声明
* 信号没有返回值,但可以有参数
* 信号就是函数的声明,只需声明,无需定义
* 使用:emit mySignal();
* 信号可以重载
*/
void mySignal();
void mySignal(int, QString);
public slots:
private:
QPushButton b;
};
#endif // SUBWIDGET_H
MainWidget.cpp
MainWidget::MainWidget(QWidget *parent)
: QWidget(parent)
{
b1.setParent(this);
b1.setText("close");
b1.move(100, 100);
b2 = new QPushButton(this);
b2->setText("abc");
connect(&b1, &QPushButton::pressed, this, &MainWidget::close);
/* &b1: 信号发出者,指针类型
* &QPushButton::pressed:处理的信号, &发送者的类名::信号名字
* this: 信号接收者
* &MainWidget::close: 槽函数,信号处理函数 &接收的类名::槽函数名字
*/
/* 自定义槽,普通函数的用法
* Qt5:任意的成员函数,普通全局函数,静态函数
* 槽函数需要和信号一致(参数,返回值)
* 由于信号都是没有返回值,所以,槽函数一定没有返回值
*/
connect(b2, &QPushButton::released, this, &MainWidget::mySlot);
connect(b2, &QPushButton::released, &b1, &QPushButton::hide);
/* 信号:短信
* 槽函数:接收短信的手机
*/
setWindowTitle("老大");
//this->setWindowTitle("老大");
b3.setParent(this);
b3.setText("切换到子窗口");
b3.move(50, 50);
//显示子窗口
//subWin.show();
connect(&b3, &QPushButton::released, this, &MainWidget::changeWin);
//处理子窗口的信号
// void (SubWidget::*funSignal)() = &SubWidget::mySignal;
// connect(&subWin, funSignal, this, &MainWidget::dealSub);
// void (SubWidget::*testSignal)(int, QString) = &SubWidget::mySignal;
// connect(&subWin, testSignal, this, &MainWidget::dealSlot);
//Qt4信号连接
//Qt4槽函数必须有slots关键字来修饰
connect(&subWin, SIGNAL(mySignal()), this, SLOT(dealSub()) );
connect(&subWin, SIGNAL(mySignal(int,QString)),
this, SLOT(dealSlot(int,QString)) );
// SIGNAL SLOT 将函数名字 -> 字符串 不进行错误检查
//Lambda表达式, 匿名函数对象
//C++11增加的新特性, 项目文件: CONFIG += C++11
//Qt配合信号一起使用,非常方便
QPushButton *b4 = new QPushButton(this);
b4->setText("Lambda表达式");
b4->move(150, 150);
int a = 10, b = 100;
connect(b4, &QPushButton::clicked,
// = :把外部所有局部变量、类中所有成员以值传递方式
// this: 类中所有成员以值传递方式
// & : 把外部所有局部变量, 引用符号
[=](bool isCheck)
{
qDebug() << isCheck;
}
);
resize(400, 300);
}
void MainWidget::dealSlot(int a, QString str)
{
// str.toUtf8() -> 字节数组QByteArray
// ……data() -> QByteArray -> char *
qDebug() << a << str.toUtf8().data();
}
void MainWidget::mySlot()
{
b2->setText("123");
}
void MainWidget::changeWin()
{
//子窗口显示
subWin.show();
//本窗口隐藏
this->hide();
}
void MainWidget::dealSub()
{
//子窗口隐藏
subWin.hide();
//本窗口显示
show();
}
MainWidget::~MainWidget()
{
}
SubWidget.cpp
#include "subwidget.h"
SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
this->setWindowTitle("小弟");
b.setParent(this);
b.setText("切换到主窗口");
connect(&b, &QPushButton::clicked, this, &SubWidget::sendSlot);
resize(400, 300);
}
void SubWidget::sendSlot()
{
emit mySignal();
emit mySignal(250, "我是子窗口");
}·