一、手动编写界面代码
Qt编程中所使用的语言是面向对象的C++,在初学GUI编程时,如果仅仅依靠Qt Designer编辑器来通过拖拽一些widget来设计界面,则会很容易迷惑我们,并且很难弄懂其中所涉及的面向对象思想,也不容易弄懂Qt GUI的一个整体结构。所以在初学Qt GUI时可以通过手动编写界面代码来理解Qt 的GUI结构。
1、组合widget方法
顾名思义,组合widget方法是通过将一些控件进行组合,形成一个主窗口。在这种方法中,首先是从Qt的GUI类库中选择一个类作为主窗口的基类,如QDialog、QWidget、QMainWindow等类中选择。以QDialog类为例,以对话框类为主窗口,然后再添加需要的其它控件类成员,可以通过布局的方式将其它控件进行布局,再将最终的布局作为主窗口对话框的布局。下面以一个简单的对话框为例,相关代码如下:
- #include <QtGui/QApplication>
- #include <QHBoxLayout> //布局管理器
- #include <QSlider>
- #include <QSpinBox>
- #include <QDialog>
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- QDialog *window = new QDialog;
- window->setWindowTitle("Enter your Age");
- QSpinBox *spinBox = new QSpinBox;
- QSlider *slider = new QSlider(Qt::Horizontal); //水平
- spinBox->setRange(0,130);
- slider->setRange(0,130);
- QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
- QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
- QHBoxLayout *layout = new QHBoxLayout;
- layout->addWidget(spinBox);
- layout->addWidget(slider);
- window->setLayout(layout);
- window->show();
- return a.exec();
- }
Qt中主要有三个主要的布局管理器:
QHBoxLayout:在水平方向上排列窗口部件,从左到右(一般情况下)。
QVBoxLayout:在竖直方向上排列窗口部件,从上到下。
QGridLayout:把各个窗口部件排列在一个网格中。
2、子类化widget方法
组合widget的方法属于面向过程的方法,当程序的规模逐渐变大时,使用这种方法会使得代码量太多,结构混杂,不利于阅读。既然是使用C++语言,使用面向对象的方法肯定是最好的选择。子类化widget的方法即为创建一个新类,这个新类就相当于一个新窗口,可以是主窗口,也可以是需要的一些对话框或窗口部分,可以继承于一些主窗口类,如QDialog、QMainWindow类等,然后将该窗口中所需要的控件类作为成员对象添加进去,然后就可以之间通过实例化该类便可以创建一个包含了一系列控件的小窗口了。还是以上述例子为例,用子类化的方法实现:相关代码如下:
头文件head.h
- <span style="font-weight: normal;"><span style="font-size:14px;">#define HEAD_H
- #include <QDialog>
- class QSpinBox;
- class QSlider;
- class test:public QDialog
- {
- Q_OBJECT
- public:
- test(QWidget *parent = 0);
- private:
- QSpinBox *spinBox;
- QSlider *slider;
- };</span></span>
- <span style="font-weight: normal;"><span style="font-size:14px;">#include "head.h"</span></span>
- <span style="font-weight: normal;"><span style="font-size:14px;">test::test(QWidget *parent):QDialog(parent)
- {
- spinBox = new QSpinBox;
- slider = new QSlider(Qt::Horizontal); //水平
- spinBox->setRange(0,130);
- slider->setRange(0,130);
- QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
- QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
- QHBoxLayout *layout = new QHBoxLayout;
- layout->addWidget(spinBox);
- layout->addWidget(slider);
- setLayout(layout);
- }</span></span>
- <span style="font-weight: normal;"><span style="font-size:14px;">#include <QHBoxLayout> //布局管理器
- #include <QSlider>
- #include <QSpinBox>
- #include <QDialog>
- #include "head.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- test *window = new test;
- window->show();
- return a.exec();
- }</span></span>
二、利用Qt Disigner设计界面
使用代码编写的方式来设计界面往往比较麻烦,而且需要修改的时候往往比较麻烦。这个时候可以使用Qt Designer编辑器来编辑界面。主要的实现方式是:首先在项目中创建一个界面ui文件,通过拖拽控件的方式画好自己的界面,设置各个widget的属性。然后我们怎么将这个ui文件使用到项目中去呢?在进行qmake之后,会自动检测到项目中的ui文件并且可以生成适当的makefile文件,makefile文件会调用Qt的用户界面编译器(User interface compiler,uic),uic会将ui文件转换成C++文件,转换结果存放在ui_[ui文件名].h中。这个头文件其实就类似于第一点中所说的子类化widget的类定义头文件,只是这里的类是根据用户所设计的界面自动生成的,即这个头文件中主要包含ui文件的类声明和界面中所使用到的一些控件的声明,以及一个用于初始化窗体的setupUi()函数。还是以第一点中所使用的例子来说明一下,过程如下:
首先我们使用Qt Designer编辑器来设计界面如下:
执行之后我们发现项目文件中会生成一个名为ui_test.h的头文件,部分代码如下:
我们可以发现ui_test.h头文件中主要是一个类Ui_test的声明,以及一个控件的声明等,这里面的内容即为我们在Qt Designer中所设计的界面。类似于我们通过拖拽控件的方式完成了子类化widget。
接下来我们要做的事情就是通过继承我们所设计的类Ui_test来创建窗口。
先在头文件中继承类Ui_test,代码如下:(注意下面继承的类名叫做Ui:test而非Ui::Ui_test的原因是ui_test.h中已将其继承为test类了,具体查看头文件中的代码)
test2.h
- <span style="font-size:14px;">#define TEST2_H
- #include <QDialog>
- #include "ui_test.h"
- class test2:public QDialog,public Ui::test
- {
- Q_OBJECT
- public:
- test2(QWidget *parent = 0);
- ~test2();
- };</span><span style="font-size: 18px;">
- </span>
- test2::test2(QWidget *parent):QDialog(parent)
- {
- setupUi(this);
- spinBox->setRange(0,130);
- slider->setRange(0,130);
- QObject::connect(spinBox,SIGNAL(valueChanged(int)),slider,SLOT(setValue(int)));
- QObject::connect(slider,SIGNAL(valueChanged(int)),spinBox,SLOT(setValue(int)));
- }
- test2::~test2()
- {
- }
- #include "test2.h"
- int main(int argc, char *argv[])
- {
- QApplication a(argc, argv);
- test2 *window = new test2;
- window->show();
- return a.exec();
- }
PS:在做这个简单的实验过程中,我还是出现了一点小问题,解决了,还是拿出来跟大家分享一下,如果有同学出现同样的错误就不用在纠结了。
错误提示是:expected class-name before '{' token
错误的位置是在类定义处:
- class test2:public QDialog,public Ui::Ui_test
- <span style="font-size:14px;">class test2:public QDialog,public Ui::test</span>
- <span style="font-size:14px;">namespace Ui {
- class test: public Ui_test {};
- } // namespace Ui</span>
- class test2:public QDialog,public Ui_test