第一次打开Qt的时候,我是一脸懵逼的。没学过c++,里面的程序都看不懂。按照套路,我开始看教程,上手实践。连着搞了3天之后,我开始渐渐明白怎么写UI。
我现在的理解是:UI = 界面设计 + 信号槽响应机制 。下面我通过实例来展示编写一个UI的大致过程(注意:这不是教程!最后贴的有专业教程!):
Step1:界面设计
首先,要创建一个项目。
.pro文件是项目的工程文件,点击此处看详细解释。
.h文件是主窗口MainWindow的头文件,可以在.h文件里声明变量、函数、信号、信号槽。
main.cpp就是主函数了,程序从这里开始。
mainwindow.cpp是主窗口的程序,在里面可以设置主窗口的布局,信号槽等。
.ui文件,我现在还是不知道这个文件的机制,不过我知道可以在里面拖放控件,就像拼积木一样设计UI,很简单,点击此处看有关内容。
一开始我用了一下.ui文件,但是由于不知道怎样对控件属性作更细的设置,所以干脆放弃,选择写代码实现。
创建好项目之后,开始做整个过程的前半部分,界面设计。
下面,在界面中添加一个按钮。
上网百度一下,常用的按钮是QPushButton,查了一下相关用法之后,就可以尝试使用了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include <QPushButton> 6 7 namespace Ui { 8 class MainWindow; 9 } 10 11 class MainWindow : public QMainWindow 12 { 13 Q_OBJECT 14 15 public: 16 explicit MainWindow(QWidget *parent = 0); 17 ~MainWindow(); 18 19 private: 20 Ui::MainWindow *ui; 21 QPushButton *button; 22 }; 23 24 #endif // MAINWINDOW_H
在.h文件里添加QPushButton的头文件#include <QPushButton> ,在private里面声明button变量,QPushButton *button;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); button = new QPushButton(this); button->setText("Button"); button->setParent(this); } MainWindow::~MainWindow() { delete ui; }
button = new QPushButton(this);//定义button变量
button->setText("Button"); //设置button属性,这里设置button的文本,其他属性百度一下就可以
button->setParent(this); //将button控件的父窗口设置为当前窗口,这句用来显示button按钮
运行效果:
到此为止,UI编写的一半——界面设计就OK了。当然要是想做更好的UI,需要添加更多的控件,各种控件百度一下基本都能找到用法。
Step2:信号槽响应机制
添加了一个按钮,一定很着急,点完之后没卵用啊!为了能够点完按钮之后给点反应,我们要用到信号与信号槽机制。按我的理解就是,你做了一件事(往往是点击按钮),之后执行相应动作(函数)。不过我的描述还是太粗浅,这里给出相对权威一点的参考。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include "mainwindow.h" #include "ui_mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); button = new QPushButton(this); button->setText("Button"); button->setParent(this); QObject::connect(button,&QPushButton::clicked,this,&MainWindow::close); } MainWindow::~MainWindow() { delete ui; }
QObject::connect(button,&QPushButton::clicked,this,&MainWindow::close);
这句话的作用就是将点击按钮与关闭窗口“绑定”在一起。这样,点完按钮之后,窗口就会关闭。详解见上面信号槽的参考。
但是这种“自带”的信号与信号槽根本满足不了需求啊,那么就需要自定义信号和自定义信号槽来实现一个自由度相对大很多的响应。
大致过程是这样的:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #ifndef MAINWINDOW_H 2 #define MAINWINDOW_H 3 4 #include <QMainWindow> 5 #include <QPushButton> 6 7 namespace Ui { 8 class MainWindow; 9 } 10 11 class MainWindow : public QMainWindow 12 { 13 Q_OBJECT 14 15 public: 16 explicit MainWindow(QWidget *parent = 0); 17 ~MainWindow(); 18 19 signals: 20 void signal(); 21 22 private slots: 23 void on_button_clicked(); 24 void receive_signal(); 25 26 private: 27 Ui::MainWindow *ui; 28 QPushButton *button; 29 }; 30 31 #endif // MAINWINDOW_H
信号声明在signals:后,信号槽声明在private slots:后。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include "mainwindow.h" 2 #include "ui_mainwindow.h" 3 4 MainWindow::MainWindow(QWidget *parent) : 5 QMainWindow(parent), 6 ui(new Ui::MainWindow) 7 { 8 ui->setupUi(this); 9 10 button = new QPushButton(this); 11 button->setText("Button"); 12 button->setParent(this); 13 14 QObject::connect(button,&QPushButton::clicked,this,&MainWindow::on_button_clicked); 15 QObject::connect(this,&MainWindow::signal,this,&MainWindow::receive_signal); 16 } 17 18 MainWindow::~MainWindow() 19 { 20 delete ui; 21 } 22 23 void MainWindow::on_button_clicked() 24 { 25 emit signal(); 26 } 27 28 void MainWindow::receive_signal() 29 { 30 this->close(); 31 }
QObject::connect(button,&QPushButton::clicked,this,&MainWindow::on_button_clicked);
QObject::connect(this,&MainWindow::signal,this,&MainWindow::receive_signal);
点击按钮和函数on_button_clicked();“绑定”在一起,点完按钮就会执行函数内容。
函数里面执行emit signal();发出自定义的信号signal();
发出signal();后,receive_signal();函数就会执行,因为前面将它俩“绑定”了。
receive_signal();函数里面执行了close();函数,效果是关闭当前界面。
有了上面两步,就可以尝试着构建功能更多的UI了,可以再添加窗口,添加其他控件,不同界面之间也可以把信号和信号槽“绑定”(不过记得要把槽设置成public的)……整个过程像堆积木一样,还挺有趣。
这里推荐两个教程,非常友好!强推!
最后,一周的时间从不会到大致明白,真的很开心,虽然其他作业都没写。