作者及原代码链接:跟小豆君学Qt
跟着学习;完整实现代码;示例截图;
QPushButton:
#include
QPushButton button;
button.setText("This is a button");
button.resize(200, 100);
button.show();
// 从大到小变化的三个button
for(int i = 0; i < 3; ++i){
QPushButton* buttonChild = new QPushButton(this);
buttonChild->setText(QString("This is a widget %1").arg(3-i));
buttonChild->resize(100 * (3-i), 100);
connect(buttonChild, SIGNAL(clicked()), buttonChild, SLOT(close())); // 点击即关闭
}
Horizontal Slider:
// 设定滑动条范围
int max = 100;
int min = 0;
ui->horizontalSlider->setMaximum(max);
ui->horizontalSlider->setMinimum(min);
QWidget:所有GUI控件的基类
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setGeometry(0, 0, 800, 600); // top, left, width, height
move(100, 100); // 窗口移动
setWindowFlags(Qt::CustomizeWindowHint|Qt::WindowStaysOnTopHint); // 隐藏标题栏
}
常用标志:
Qt::Widget 默认窗口
Qt::Dialog 对话框
Qt::SplashScreen 启动窗口
Qt::SplashScreen 在还没有展示出主界面前的启动画面
Qt::FramelessWindowHint 隐藏标题栏,并且去掉窗口的边框,窗口不能移动和缩放。
Qt::CustomizeWindowHint 隐藏标题栏,不会去掉窗口的边框,窗口不能移动,但可以缩放。
Qt::WindowStaysOnTopHint 使窗口始终处于最顶部。类似于播放器中的总在最前功能。
设置背景色:
setAutoFillBackground(true);
QPalette pa = this->palette();
pa.setBrush(QPalette::Background, QBrush(Qt::cyan));
setPalette(pa);
窗口属性:
setWindowOpacity(0.8); // 透明度
setWindowTitle("LX Demo"); // 标题
setToolTip("hang"); // 鼠标悬停提示
resize(400, 200); // 调整窗口大小
信号和槽:Qt最明显区别于其它开发框架的特征
信号就是命令,槽就是执行命令;
/***
static QMetaObject::Connection connect(
const QObject *sender, //信号发送对象指针
const char *signal, //信号函数字符串,使用SIGNAL()
const QObject *receiver, //槽函数对象指针
const char *member, //槽函数字符串,使用SLOT()
Qt::ConnectionType = Qt::AutoConnection//连接类型,一般默认即可
);
***/
connect(object1, signal, object2, slot);
// e.g
connect(pushButton, SIGNAL(clicked()), dialog, SLOT(close()));
/***
static QMetaObject::Connection connect(
const QObject *sender, //信号发送对象指针
const QMetaMethod &signal,//信号函数地址
const QObject *receiver, //槽函数对象指针
const QMetaMethod &method,//槽函数地址
Qt::ConnectionType type = Qt::AutoConnection//连接类型,一般默认即可
);
Qt5新增,使得在编译期间就可以进行拼写检查,参数检查,类型检查,并且支持相容参数的兼容性转换;
***/
// e.g
connect(pushButton, QPushButton::clicked, dialog, QDialog::close);
信号:
1. 声明信号使用signals关键字,发送信号使用emit关键字;
2. 信号声明是公共的,不能在signals前加public,private, protected;
3. 信号没有返回值,返回值都用void;
4. 信号都不需要定义;
5. 必须直接或间接继承自QOBject类,并且开头私有声明包含Q_OBJECT;
6. 当一个信号发出时,会立即执行其槽函数,等待槽函数执行完毕后,才会执行后面的代码,如果一个信号链接了多个槽,那么会等所有的槽函数执行完毕后才执行后面的代码,槽函数的执行顺序是按照它们链接时的顺序执行的;
7. 在链接信号和槽时,可以设置链接方式为:在发出信号后,不需要等待槽函数执行完,而是直接执行后面的代码;
8. 信号参数的个数不得少于槽参数的个数;
槽:
1. 槽其实就是普通的C++函数,它唯一特点就是能和信号链接。当和它链接的信号被发出时,这个槽就会被调用;
2. Qt5中每个函数都可以被当作是槽函数,可以使用Lambda表达式来作为槽;
// 新建一个widget项目, ui中拖入horizontal slider, lineEdit, label
// 效果:lineEdit中输入0-100整数,滑动条跟着动,label文字和lineEdit保持一致
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
int max = 100;
int min = 0;
ui->horizontalSlider->setMaximum(max);
ui->horizontalSlider->setMinimum(min); // 滑动条上下限
QIntValidator* validator = new QIntValidator(min, max, this);
ui->lineEdit->setValidator(validator); // 规范输入只能是整数值
// lineEdit 发出 textChanged 信号, horizontalSlider 执行 lineEditChanged 槽函数
connect(ui->lineEdit, &QLineEdit::textChanged, this, &Widget::lineEditChanged);
// horizontalSlider 发出 sigShowVal 信号, label 执行 setText 槽函数
connect(this, SIGNAL(sigShowVal(QString)), ui->label, SLOT(setText(QString)));
}
void Widget::lineEditChanged(const QString &text){
int val = text.toInt();
ui->horizontalSlider->setValue(val);
emit sigShowVal(text);
}
UI中编辑信号和槽:
1. F4编辑:将控制控件和被控制控件连起来,选择相应的槽函数(内置);
2. F3退出编辑 ;
3. 右键选择控制控件,转到槽函数,进行进一步编辑;
4. QObject::setObjectName()方法为对象设置名称;
5. QMetaObject::connectSlotsByName()启用自动关联;
6. 用下划线"_"将"on",“对象名”,“信号名”连接后命名的函数,即:on_对象名_信号名(参数)
// .h 文件中自动生成
private slots:
void on_pushButton_toggled(bool checked);
QSignalMapper:
这个类可以连接多个按钮,匹配发送信号的对象对应的整数、字符串,窗口指针,继承于QObject的对象参数重新发送它们。
// 计算器界面Demo,点击button显示数字
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QVBoxLayout* vLayout = new QVBoxLayout(this); // 垂直布局
QLineEdit* edit = new QLineEdit; // 文本框
edit->setAlignment(Qt::AlignRight); // 靠右对齐
vLayout->addWidget(edit);
// 创建信号匹配器
QSignalMapper* signalMapper = new QSignalMapper(this);
QGridLayout* gridLayout = new QGridLayout; // 网格布局
for(int i=0; i<10; ++i){
QString txt = QString::number(i);
QPushButton* button_1 = new QPushButton(txt); // 定义button
// button_1 发射 clicked 信号, signalMapper信号匹配器 执行 匹配槽函数
connect(button_1, SIGNAL(clicked()), signalMapper, SLOT(map()));
signalMapper->setMapping(button_1, txt); // 信号匹配
gridLayout->addWidget(button_1, i / 3, i % 3); // 添加布局,(widget, row, col)
}
// 信号匹配器 发送 mapped 信号, 文本框 执行 setText 槽函数
connect(signalMapper, SIGNAL(mapped(QString)), edit, SLOT(setText(QString)));
vLayout->addLayout(gridLayout); // 将网格布局添加至垂直布局
resize(200, 200);
}
其他:
1. 判断信号是哪个对象发来的,调用sender()函数获取对象指针,返回为QObject指针:QObject* sender() ;
2. 不需要信号槽连接时,可使用disconnect()进行解绑定,写法和connect一样,只需要将connect换成disconnect即可;
moc预编译器 moc(Meta-Object Compiler)元对象预编译器
moc读取一个c++头文件。如果它找到包含Q_OBJECT宏的一个或多个类声明,它会生成一个包含这些类的元对象代码的c++源文件,并且以moc_作为前缀。信号和槽机制、运行时类型信息和动态属性系统需要元对象代码。