我这里的qt版本如下:
创建第一个Qt项目
这里先用代码的方式写Qt界面。首先先建立我们的第一个Qt界面。
当我们打开Qt Creator时的界面如下所示:
然后我们新建自己的项目:
1.点击Projects旁边的New,然后选择Application,再点击Qt Widgets Application
2.在跳出的对话框中输入项目名称,然后选择存储的路径。
3.安装提示一步一步点下去,然后在Details可以看到下面的图,然后输入Class name ,这里我们选择QWidget,然后把Generate form前面的对勾去掉【再后面的章节再说这里】【这里需要说一句,Base class下拉菜单中有三个选项,QWidget、QMainWidget、QDialog,这三个类继承关系,后两个类是第一个类的子类,QWidget是一个空白的主窗口,QMainWidget是包含菜单栏的窗口,QDialog是一个对话框窗口】
4.然后继续往下点,直到Kits.这里的选择需要根据自己的VS环境来选择,我的是VS2017,所以选择这个。
5.然后点到Summary可以看到下图我红框框出来的部分(要添加的文件,这几个文件我会在后面进行介绍)
这里的.pro文件就是我们的project的文件,就相当于VS中的.sln文件(解决方案)。
创建完成以后如下:
介绍main函数
main.cpp文件就是我们的程序入口文件。
头文件中的mywidget.h就是前面创建项目时添加的头文件,QApplication是创建QT应用程序的头文件。
代码和c++一样,int argc参数是命令行参数的数量,argv是命令行变量的数组
创建的对象a在Qt中有且仅有一个。
1.myWidget w为窗口对象,该对象的父类为QWidget,一个空窗口。
2.窗口对象默认不会显示,需要调用show()方法进行显示窗口。
3.return a.exec()是进行消息循环机制(就像个死循环)
此时你运行后会跳出一个空白窗口,如下图:

生成上述的空白窗口后,我们可以在我们的项目文件中找到对应的exe文件,当我们直接点击这个exe文件就可以直接跳出我们创建的界面。
工程文件.pro文件
然后在我们的界面左侧可以看到有个.pro文件,也就是我们的工程文件,我们可以点开它,如下图所示。
其中
QT += core gui这行代码是Qt的两个模块core模块(核心模型)和gui模块(图形模块)。
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 这行代码表示Qt版本大于4版本就有个Qwidgets模块。
CONFIG += c++11表示要用c++11.
SOURCES指定了项目中源文件列表,这里包含了main.cpp和mywidget.cpp文件。
HEADERS是头文件列表,这里只有mywidget.h
然后是一一些部署规则。
mywidget.h头文件说明
接下来打开我们的mywidget.h看看有什么。
开头的两行就是导入一下包。
然后我们可以看到我们创建的myWideget这个类是继承父类QWideget的。
Q_OBJECT是一个宏,允许我们的类使用信号和槽(这个在后面会讲到)。
然后在构造函数中可以看到这是一个有参构造,参数为QWidget类型的指针,便于创建子类对象时传入父对象。意思就是:我们创建的这个对象是添加到另一个QWidget布局中,这种的好处就是便于内存的管理,比如当父对象销毁的时候,子类对象也会销毁,用父类去管理子类。
mywidget.cpp文件说明
然后我们看该头文件中的构造函数的定义。(在mywidget.cpp中)
可以看到在构造函数的定义中使用了成员初始化列表的方式初始化参数parent,这里调用了QWidgetg的有参构造函数。
介绍了上面的几个工程文件,接下来我们可以尝试在我们的空白界面上丰富一下我们的界面,比如我这里添加一个按钮的功能。
添加按钮--QPushButton
我们可以在左侧的帮助界面先来了解一下QPushButton这个类。
首先可以看到,如果我们需要在界面上添加一个按钮,那么就需要导入头文件QPushButton.
Inherits是父类,也就是说我们这个QPushButton的父类是QAbstractButton。
QCommandLinkButton是QPushButton下的子类。
无参构造创建按钮对象
然后创建我们的第一个按钮,在mywidget.cpp中代码和图如下:这里需要注意一下,如果你这里直接调用btn->show()函数,那么按钮会在一个单独的窗口显示,我们需要将按钮添加在我们的窗口上,因此需要设计父亲setParent(this)表示在当前窗口上添加按钮,并设置按钮文字。
#include "mywidget.h"
#include <QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
//创建按钮
QPushButton *btn = new QPushButton;
//btn->show(); //以顶层方式弹出窗口控件(也就是单独一个窗口显示按钮)
//如果希望btn在我们定义的窗口中显示
btn->setParent(this);
//显示文本
btn->setText("按钮");
}
myWidget::~myWidget()
{
}
有参构造创建按钮
然后我们再来看一种创建按钮的方式,代码如下:
可以在创建对象的时候调用QPushButton的有参构造创建对象,这样就相当于将上面的几个步骤合并了。
#include "mywidget.h"
#include <QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
QPushButton *btn2 = new QPushButton("按钮",this);
}
myWidget::~myWidget()
{
}
但这种有个弊端,就是运行程序后发现窗口的size很小,和控件(按钮)的大小一样。
设置窗口大小
因此我们可以设置一下窗口的大小。用resize函数即可。代码如下:
然后我们可以将上面添加的两个按钮都在同一界面中显示出来,这里需要注意的是,我们需要用move函数来移动其中的一个按钮到指定位置,要不然这两个按钮就重合了。如下图:
这里的位置也是需要说明一下,对于窗口而言,左上角为原点坐标,x轴向右,y轴正半轴向下(和图像坐标一样)。
设置固定窗口大小
我们通过上面的操作新建了一个含有两个按钮的窗口,并且给窗口大小设置的为600x400,但会发现我们可以随意拖动这个窗口大小,那么如果我们希望窗口大小就必须固定为600x400,用户不能随意拖动怎么办?
实际很简单,我们只需要调用setFixSize()函数即可。代码如下:
#include "mywidget.h"
#include <QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
//创建按钮
QPushButton *btn = new QPushButton;
//btn->show(); //以顶层方式弹出窗口控件(也就是单独一个窗口显示按钮)
//如果希望btn在我们定义的窗口中显示
btn->setParent(this);
//显示文本
btn->setText("按钮");
QPushButton *btn2 = new QPushButton("按钮",this);
resize(600,400);
setFixedSize(600,400); //固定窗口大小
btn->move(100,100);
setWindowTitle("mywidget");
}
myWidget::~myWidget()
{
}
信号和槽
在前面创建的按钮中会发现,我们点击按钮没有任何反应,这是因为虽然我们有点击的动作,但是没有可以执行的方法,因此就需要信号和槽。
为了更好的理解信号和槽,这里先举个例子,比如人要摩擦神灯,灯神会从神灯里出来,就像下面的图(图像来自chatgpt)。那么这里的人就相当于是我们的按钮,摩擦就是点击按钮,对象就是灯神,执行的就是灯神出来可以许愿。
对象和对象之间(比如人和神灯)就需要进行连接。而人是信号的发送者,摩擦的动作就是发送的信号,神灯就是信号的接受者,灯神就会出来满足愿望就属于信号的处理,那么伪代码如下:
connect(信号的发送者,发送的具体信号,信号的接受者,信号的处理(槽))
比如我们现在要实现一个功能,就是点击按钮后就关闭整个窗口。那么先来理清一下每个对象和信号:
1.信号的发送者:我们创建的按钮
2.发送的具体信号:点击动作
3.信号的接受者者:我们创建的窗口
4.信号槽:关闭窗口
实现代码如下:
#include "mywidget.h"
#include <QPushButton>
myWidget::myWidget(QWidget *parent)
: QWidget(parent)
{
resize(600,400);//设置窗口大小
setFixedSize(600,400);//设置固定窗口大小
setWindowTitle("myWidget");//设置窗口标题
//创建按钮
QPushButton *btn = new QPushButton("关闭按钮",this);
btn->move(300,200);//移动按钮
//实现点击按钮后关闭窗口的功能
connect(btn,&QPushButton::clicked,this,&myWidget::close);
}
myWidget::~myWidget()
{
}
实现自定义槽函数
通过上面的操作我们实现了一个点击按钮后关闭窗口的功能的实现。那么可以发现这里的关闭功能(信号槽函数)是已经写好的,那么我们希望自己写一个槽函数怎么做呢?
比如我们现在要实现一个功能,就是当老师下课后,老师走了,学生要去上厕所。
我们这里在项目中创建两个类,一个Teacher类,一个Student类。创建的方法也很简单,右击我们的项目,然后添加文件,选择c++文件即可,只是在选择Base class的时候要注意下,因为我们的Teacher和Student并不属于控件,因此只需要选择QObject,这样方便我们的内存管理。
创建好后的代码如下:
可以看到在我们定义的好的头文件Teacher.h中有个signals和slots,这里可以让我们写信号和槽函数(槽函数写在student中)。
这里需要注意的是,在signals中自定义的时候,是可以不用实现的,只需要声明即可。
如下:
#ifndef TEACHER_H
#define TEACHER_H
#include <QObject>
class Teacher : public QObject
{
Q_OBJECT
public:
explicit Teacher(QObject *parent = nullptr);
signals:
//自定义信号
//返回值是void,只需要声明,不需要实现
void Eixt();
public slots:
};
#endif // TEACHER_H
对于Student类的声明(声明是在.h文件中)和实现(实现是在.cpp文件中)如下:
# Student的声明,在Student.h文件中
#ifndef STUDENT_H
#define STUDENT_H
#include <QObject>
class Student : public QObject
{
Q_OBJECT
public:
explicit Student(QObject *parent = nullptr);
signals:
public slots:
//参函数是需要声明也需要实现的。
void goWC();
};
#endif // STUDENT_H
#Student的槽函数实现,在.cpp文件中
#include "student.h"
#include <string>
#include<iostream>
using namespace std;
Student::Student(QObject *parent) : QObject(parent)
{
}
void Student:: goWC()
{
cout<<"go to WC"<<endl;
}
然后点击我们的widget.h文件,声明我们的Teacher和Student的对象。【注意后面所有的代码声明是在.h文件中,实现(包括成员变量的初始化等)均在.cpp实现】
widget.h声明
这里我们触发信号是aferClass
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include"teacher.h"
#include"student.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
//创建老师和学生对象
Teacher* teacher;
Student* student;
void afterClass();
};
#endif // WIDGET_H
widget.cpp实现
如果要触发一个状态要用到关键字emit 这个触发状态就好比点击按钮的点击动作。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->teacher = new Teacher(this);
this->student = new Student(this);
connect(teacher,&Teacher::hungry,student,&Student::goWC);
this->afterClass();
}
void Widget::afterClass()
{
//老师下课
//触发的关键字:emit
emit teacher->Exit();
}
Widget::~Widget()
{
delete ui;
}
这里的信号的发送者就是定义的对象teacher,发送的信号就是我们的定义的函数afterClass,信号的接受者就是student,信号槽就是goWC。
可以看到当触发了下课的信号后,就触发了学生要上厕所。
上面就是我们自定义的信号和槽函数.然后可以简单的实现一下点击下课按钮,学生去wc.
代码如下:
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//创建按钮
QPushButton* btn_afterClass = new QPushButton("下课",this);
btn_afterClass->move(200,200);
//设置窗口大小
resize(600,400);
setFixedSize(600,400);
//实现功能:点击下课按钮后学生上厕所
student = new Student(this);
connect(btn_afterClass,&QPushButton::clicked,student,&Student::goWC);
}
效果如果所示:
QMainWindow
QMainWindow和之前的QWidget是有区别的,前者包含了菜单栏、工具栏、多个锚接部件(也可以称为浮动窗口)、一个状态栏、一个中心部件等,后者是一个空白窗口。
新建一个项目,创建方式和之前一样,只不过在创建的选类型时要选择QMainWindow.
创建菜单
创建菜单栏需要导入头文件<QMenuBar>
我们现在想要在窗口中创建一个菜单栏,然后调用setMenuBar放在当前中,那么代码如下:
这里需要注意,在setMenuBar(QB)后如果不添加菜单那么界面中是不会显示菜单的。
#include "mainwindow.h"
#include<QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600,400);
setFixedSize(600,400);
//创建菜单栏
QMenuBar* QB = menuBar();
//将菜单栏放到窗口中
setMenuBar(QB);
//创建菜单
QMenu* FileMenu = QB->addMenu("File");
QMenu* ToolsMenu = QB->addMenu("tools");
}
MainWindow::~MainWindow()
{
}
效果图如下:
然后我们如果希望在菜单中添加菜单项(比如在File中添加一个Open),代码如下:
只需要调用addAction()函数即可。
#include "mainwindow.h"
#include<QMenuBar>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600,400);
setFixedSize(600,400);
//创建菜单栏
QMenuBar* QB = menuBar();
//将菜单栏放到窗口中
setMenuBar(QB);
//创建菜单
QMenu* FileMenu = QB->addMenu("File");
QMenu* ToolsMenu = QB->addMenu("tools");
//添加菜单项
FileMenu->addAction("Open File");
FileMenu->addSeparator();//可以在两个选项中添加分割线
FileMenu->addAction("New");
}
创建工具栏
创建工具栏需要用的导入头文件<QToolBar>。
addToolBar是将工具栏放在当前窗口
设置工具栏停靠区域
此时的工具栏默认是在上方。如果我们需要让工具栏在指定位置可以像下图一样。
如果只允许让工具栏停靠在左右侧,那么可以调用函数:
toolbar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
设置工具栏浮动
设置浮动,即工具栏是可以浮动的,代码如下:
//添加工具栏
QToolBar* toolbar = new QToolBar(this);
addToolBar(toolbar);
toolbar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
toolbar->setFloatable(false);
设置工具移动
设置是否可以移动:可以设置工具栏是否可以移动
//添加工具栏
QToolBar* toolbar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolbar);
toolbar->setMovable(false);
在工具栏中添加选项:
我们还可以在工具栏中添加控件,比如添加一个按钮:
或者用下面的方法添加按钮到工具栏也是可以的。
创建状态栏
创建状态栏需要导入头文件<QStatusBar>
widget.cpp完整代码:
#include "mainwindow.h"
#include<QMenuBar>
#include<QToolBar>
#include<QPushButton>
#include<QStatusBar>
#include<QLabel>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600,400);
setFixedSize(600,400);
//创建菜单栏
QMenuBar* QB = menuBar();
//将菜单栏放到窗口中
setMenuBar(QB);
//创建菜单
QMenu* FileMenu = QB->addMenu("File");
QMenu* ToolsMenu = QB->addMenu("tools");
//添加菜单项
QAction* openAction = FileMenu->addAction("Open File");
FileMenu->addSeparator();//可以在两个选项中添加分割线
QAction* newAction = FileMenu->addAction("New");
//添加工具栏
QToolBar* toolbar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolbar);
toolbar->setMovable(false);
//添加工具
toolbar->addAction("Welcome");
toolbar->addAction("Project");
//在工具栏中添加按钮(控件)
QPushButton* btn = new QPushButton("exit",this);
toolbar->addWidget(btn);
//创建一个状态栏
QStatusBar* statusbar = new QStatusBar();
setStatusBar(statusbar);//放到窗口中
//在状态栏中放入一个label,需要导入QLable头文件
QLabel* label = new QLabel("提示信息",this);
statusbar->addWidget(label);
}
MainWindow::~MainWindow()
{
}
铆接部件(浮动窗口)的创建
需要导入头文件<QDockWidget>
设置浮窗默认停靠区域
如果希望设置停靠区域(只可以上下),则代码如下:
//创建铆接(浮动窗口)控件
QDockWidget* Qd = new QDockWidget("浮动窗口",this);
addDockWidget(Qt::BottomDockWidgetArea, Qd);
Qd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
完整代码:
#include "mainwindow.h"
#include<QMenuBar>
#include<QToolBar>
#include<QPushButton>
#include<QStatusBar>
#include<QLabel>
#include<QDockWidget>
#include<QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600,400);
setFixedSize(600,400);
//创建菜单栏
QMenuBar* QB = menuBar();
//将菜单栏放到窗口中
setMenuBar(QB);
//创建菜单
QMenu* FileMenu = QB->addMenu("File");
QMenu* ToolsMenu = QB->addMenu("tools");
//添加菜单项
QAction* openAction = FileMenu->addAction("Open File");
FileMenu->addSeparator();//可以在两个选项中添加分割线
QAction* newAction = FileMenu->addAction("New");
//添加工具栏
QToolBar* toolbar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolbar);
toolbar->setMovable(false);
//添加工具
toolbar->addAction("Welcome");
toolbar->addAction("Project");
//在工具栏中添加按钮(控件)
QPushButton* btn = new QPushButton("exit",this);
toolbar->addWidget(btn);
//创建一个状态栏
QStatusBar* statusbar = new QStatusBar();
setStatusBar(statusbar);//放到窗口中
//在状态栏中放入一个label,需要导入QLable头文件
QLabel* label = new QLabel("提示信息",this);
statusbar->addWidget(label);
//创建铆接(浮动窗口)控件
QDockWidget* Qd = new QDockWidget("浮动窗口",this);
addDockWidget(Qt::BottomDockWidgetArea, Qd);
Qd->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
//加入中心部件
QTextEdit* edit = new QTextEdit(this);
setCentralWidget(edit);
}
MainWindow::~MainWindow()
{
}
资源文件的添加
这里我们在创建新项目的时候选择创建ui文件。如下:
双击ui文件打开后如下所示:
之前我们在添加按钮等控件的时候都是用代码new出来,这样很不方便,现在我们可以直观的用ui界面用鼠标拖拽来设计。
然后我们可以在这里的菜单栏直接写入我们的控件。比如我在文件选项的下拉菜单中创建一个新建的选项(注意如果要输入中文,需要在对应控件的text进行修改)
同时在界面的右上角也能看到,ui文件中自动给我们加入的了工具栏,菜单栏等便于我们的操作。
我们还可以在ui文件的左侧的工具栏找我们需要的东西,比如按钮,铆接部件,直接拖过去即可,然后再右边修改相应的属性。比如允许停靠的区域等。
我们平常在点击文件->新建按钮的时候,有些软件的新建前面可能会有个小图标。那么这个图标怎么添加呢?有两种方法:
方法1:
直接在icon中添加相应的图像。
方法二:
在代码中添加相应的图像,在添加图像的时候,你需要知道要给哪个对象添加,比如我要给"新建"的选项前面添加图像,那么我们就要找到他的对象,这个对象也很好找,如下:
这个actionNew就是我们的“新建”选项,当然你也可以修改,但要记住该对象。
代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->actionNew->setIcon(QIcon("F:\\facenet-pytorch\\img\\1_001.jpg"));
}
MainWindow::~MainWindow()
{
delete ui;
}
(可以看到我这里传入的图像是在F盘的其他地方,这样有个弊端,在别人的电脑上加载不上,因此我们需要添加资源到Qt中)步骤如下:
步骤1.将需要添加的资源放到你的工程下,比如我把图像文件夹放到工程下。
步骤2:返回Qt,右键你的项目-->添加新文件-->选择Qt-->Qt Resource File
步骤3.起名字,这里根据自己的需要写。
添加完成后如下图:
然后添加前缀(Add Prefix,没有前缀就写一个/),然后点击Add Files。然后把要添加的资源图像添加进去,然后点一下编译(就是界面左下方的小锤子)。
通过上面我们添加的资源文件到Qt中,那么我们现在应该怎么使用它呢?
代码如下,其实就是用图像的相对路径。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//ui->actionNew->setIcon(QIcon("F:\\facenet-pytorch\\img\\1_001.jpg"));
//使用Qt资源,语法为:":+前缀名+文件名"
ui->actionNew->setIcon(QIcon(":/img/1_002.jpg"));
}
MainWindow::~MainWindow()
{
delete ui;
}
添加模态和非模态对话框
现在我们要实现一个功能,就是依次点击窗口上的文件->新建后可以选择新建的文件。那么这就要用到之前的信号和槽了。
模态对话框
现在利用模态创建一个对话框(需要导入QDialog头文件)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//实现点击新建按钮弹出一个对话框
connect(ui->actionNew,&QAction::triggered,[=](){
//弹出对话框
//模态对话框 非模态对话框
//非模态指:创建对话框后可以操作其他对话框
//模态对话框:创建对话框后不可以操作其他对话框
//创建模态对话框
QDialog Qld(this);
Qld.exec();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
注意:这里为什么Qld2的对象是个指针呢?也就是对象在堆区,这是因为在前面的模态对话框中,对象是在栈区,通过阻塞的方法显示窗口。而在非模态对话框中,如果对象是在栈区,那么就会很快释放,窗口就会一闪而过。
非模态对话框
消息对话框
消息对话框就好比警告对话框,对应的对象为QMessageBox
比如我们现在要实现一个跳出报错的对话框:
直接调用QMessageBox中的critical方法即可。
比如我们再创建一个询问的对话框。
代码为:
//创建询问的对话框
QMessageBox::question(this,"question","提示");
如上图,在询问对话框中有两个按钮"yes"或"no"。那我们是否可以更改为其他的呢?答案肯定是可以的。代码和效果图如下:
读取文件对话框
比如我们要打开一个文件,此时我们就要创建一个对话框用于选择我们的文件。如下图所示:
读取文件对话框需要导入头文件<QFileDialog>,打开文件就需要调用getOpenFileName函数,然后可以选择的文件,对应代码和效果图如下,如果需要获取选择的文件路径,那么可以用QString进行接收。
connect(ui->actionOpen, &QAction::triggered,[=]()
{
QString File_path = QFileDialog::getOpenFileName(this,"打开文件","E:\\Qt\\Qt_test");
cout << "FileName is :" << File_path.toStdString() << endl;
});
布局
学习布局,我们可以做一个简单的登录窗口为例。
我们用Label控件放"用户名"和"密码",用Line Edit控件可以输入用户名和密码。
如下图所示,但会发现一个奇怪的现象,我们在缩放窗口大小的时候会发现控件不会跟着一起缩放。因此我们就需要设置布局!
![]() | ![]() |
那么怎么设置布局呢?在我们的Qt界面中有水平布局和垂直布局。
然后我们再观察登录界面中的各个控件的关系,可以看到“用户名”和后面的输入框是水平布局,方法1:
将水平布局拖动界面上,然后将两个控件放进去;
方法2:
方法1不够灵活,因此可以采用方法二。在我们左侧的工具栏中有个Widgets控件 。
我们将其拖放到界面上,然后再把"用户名"label和输入框控件放进Widget中,再点击水平分布,这样两个控件就分布好了(我们可以拖动这个Widgets放在任意一个地方了)。或者说两个控件由该Widget管理,我们还可以将这个Widget对象名修改为User_Widget.如下图:
同理,我们可以将其他控件也这样排布。然后我们将用户名、密码、按钮控件布局好后,又可以看到这三个部分的布局呈垂直布局,那么我们点击centralwidget修改为垂直布局。
不过可以看到这个界面是有些丑的,但这些控件可以随着窗口大小的变化而改变。接下来我们将继续调整,我们只需要在控件中加入对应的弹簧即可。修改弹簧的属性(sizeType)可以让其伸缩或者固定。如果是选择固定,还可以修改sizeHint修改固定的宽度和高度。这里需要注意的一点是,如果全局没有布局(也就是最大的窗口没有布局),那么弹簧就不会起作用的。
同时不止有上面的水平布局和垂直布局,针对有些控件的排版方式是几行几列的还可以用我们的网格布局。如果需要调整某个widget的宽度,可以选择该widget后在属性值找到SizePolicy中的垂直策略为Fixed。具体效果如下:
(输入密码的时候默认是明文的,如果想隐藏起来,那么可以点击密码的文本框,找到echoMode修改为password)。
总结:
在做布局的时候,先不要着急做水平或者垂直布局,而是用Widget控件,将你需要布局控件放到该Widget控件中,然后选择该Widget进行对应的布局(包括加弹簧),最后再对大的Widget做个布局即可。
按钮组
前面已经学过了一般的按钮PushButton。然后再看看还有没有其他的按钮。
Tool Button如下图,其实就可以理解为我们微信聊天时的好友列表:
选项按钮:
QListWidget
QListWidget我们可以用来做微信好友列表的这类形式,将诸多好友添加在里面。
QTreeWidget
QTreeWidget我们可以再工具栏中找到,找到后直接推拽到窗口上即可。
然后我们现在要在该TreeWidget上加个标题(水平头):
然后再给里面放入信息。
如果还需要给Tom下放东西,代码和效果如下: