Qt学习笔记

入门

创建一个项目

步骤

Create Project > Application(Qt) > Qt Widgets Application

generate form:创建界面,暂不选

Base class

这里选择个QWidget(非窗口的普通类可以选顶级类QObject,以便加入对象树)

  • QWidget
    QDialogQMainClass的父类,是个空窗口
  • QDialog
    对话框
  • QMainClass
    一些菜单栏、工具栏、状态栏之类的
main.cpp
#include "widget.h"

//应用程序类头文件
#include 

/**
 * 程序入口
 * @brief qMain
 * @param argc 命令行参数个数
 * @param argv 命令行参数数组
 * @return 
 */
int main(int argc, char *argv[])
{
    //实例化出一个应用程序对象a,该对象有且只有一个
    QApplication a(argc, argv);
    
    //窗口类(QWidget的子类)
    Widget w;
    
    //显示窗口
    w.show();
    
    /*
     * 进入消息循环机制(阻塞),关闭窗口时退出
     */
    return a.exec();
}
widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include 

class Widget : public QWidget
{
    Q_OBJECT //用于支持信号和槽的宏

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
};
#endif // WIDGET_H

命名规范

java

常用快捷键

  • 查询:ctrl + f
  • 注释:ctrl + /
  • 帮助:选中 + F1
  • 缩放:ctrl + 滚轮
  • 行移动:ctrl + shift + 上|下
  • 编码格式化:ctrl + i
  • 源文件与头文件切换:f4

QPushButton

widget.cpp,须引入头文件#include

// widget.cpp

#include "widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //设置窗口名称
    setWindowTitle("测试QPushButton");
    
    //设置当前窗口大小:用户可缩放
    //resize(600, 400);

    //设置当前窗口大小:用户不可缩放
    setFixedSize(600, 400);

    /**
     * 创建一个按钮(对象)
     */
    /*方式一*/
    QPushButton* btn1 = new QPushButton;
    //设置父窗口
    btn1->setParent(this);
    //设置内容
    btn1->setText("按钮1");
    /*方式二*/
    QPushButton* btn2 = new QPushButton("btn2", this);
    
    //移动按钮
    btn2->move(100, 0);
}

Widget::~Widget()
{
}

对象树

无需关心对象的释放

Qt中对于new出来的对象,如果是QObject及其衍生类,都无需关心其内存的释放

QObject是以对象树的形式组织起来的

当创建一个QObject对象时,QObject的构造函数会接收一个QObject指针作为参数,名为parent,也就是对象指针

所以,在创建QObject对象时,可以提供一个它的父对象,而我们即将创建的这个QObject,就会被加入到父对象的children()列表中

当父对象析构的时候,这个列表中的所有对象也都会被调用析构

这里的父子对象指的是父子窗口的含义

当一个QObject对象在堆上创建时,Qt会同时为其创建一个对象树,要注意的是,对象树中的对象的顺序时没有定义的,所以,销毁这些对象的顺序也是未定义的

任何对象树种的QObject对象delete的时候,如果这个对象有parent,那么会同时将这个对象从它的parentchildren中移除;

同时,如果它自身的children()中的对象也会被delete

如果QObject在栈上被创建,Qt也一样会这样操作

构造与析构顺序

构造:QObject最先开始

析构:QObject最后执行
Qt学习笔记_第1张图片

注意:对于打印的顺序,会先打印父对象中的析构函数中,因为这时候并没有进行释放操作,而只是追踪操作,即判断是否还有下级子对象,只有在确定没有子对象时才开始由子到父的顺序进行对象的释放

信号和槽

connect

语法

connect(信号发送者, 发送的信号, 信号接收者, 处理的槽函数)

案例:点击按钮关闭窗口
#include "widget.h"
#include 
#include "mypushbutton.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    MyPushButton* btn = new MyPushButton;
    btn->setText("点我关闭");
    btn->setParent(this);

    connect(btn, &QPushButton::clicked, this, &QWidget::close);
}

Widget::~Widget()
{
    qDebug() << "Widget 析构函数调用";
}

自定义信号和槽

书写规范
信号
  • 写在signals下,只需要声明,不需要实现
  • 返回值为void,可以有参数,且可以重载
  • 写在public slots
    5.0开始可以写成全局函数 或public下成员函数 或直接用lambda表达式
  • 需要声明,同时也要有实现
  • 返回值一般用void,可以有参数,也可以重载

案例

connect(班长, 起立, 学生, 老师好)

班长类
  • classmonitor.h
    #ifndef CLASSMONITOR_H
    #define CLASSMONITOR_H
    
    #include 
    
    class ClassMonitor : public QObject
    {
        Q_OBJECT
    public:
        explicit ClassMonitor(QObject *parent = nullptr);
    
    signals:
        void standUp();
    };
    
    #endif // CLASSMONITOR_H
    
    
  • classmonitor.cpp
    #include "classmonitor.h"
    
    ClassMonitor::ClassMonitor(QObject *parent)
        : QObject{parent}
    {
    
    }
    
学生类
  • student.h
    #ifndef STUDENT_H
    #define STUDENT_H
    
    #include 
    
    class Student : public QObject
    {
        Q_OBJECT
    public:
        explicit Student(QObject *parent = nullptr);
    
    signals:
    
    //槽函数除了写在这的public slots中,也可以写在全局函数或者public下
    public slots:
        void greeting();//需要在源文件中实现
    };
    
    #endif // STUDENT_H
    
    
  • student.cpp
    #include "student.h"
    #include 
    
    Student::Student(QObject *parent)
        : QObject{parent}
    {
    
    }
    
    void Student::greeting() {
        qDebug() << "老师好 ~~ ";
    }
    
Widget
  • widget.h
    #ifndef WIDGET_H
    #define WIDGET_H
    #include "classmonitor.h"
    #include "student.h"
    #include 
    
    class Widget : public QWidget
    {
        Q_OBJECT
    
    public:
        Widget(QWidget *parent = nullptr);
        ~Widget();
    
        ClassMonitor * monitor;
        Student * student;
    
        void classBegin();
    };
    #endif // WIDGET_H
    
  • widget.cpp
    #include "widget.h"
    
    Widget::Widget(QWidget *parent)
        : QWidget(parent)
    {
        //传入this,将其放入对象树中
        this->monitor = new ClassMonitor(this);
        this->student = new Student(this);
    
        //创建信号槽:班长喊起立,学生喊老师好
        connect(monitor, &ClassMonitor::standUp, student, &Student::greeting);
        //上课:触发信号槽
        classBegin();
    }
    
    Widget::~Widget()
    {
    }
    
    /**
     * 上课:触发班长的《起立》信号
     * 班长:实例对象要和connect的一致
     * @brief Widget::classBegin
     */
    void Widget::classBegin() {
        emit this->monitor->standUp();
    }
    
    
    
    

重载

班长类
  • classmonitor.h
    //...
    signals:
        void standUp();
        void standUp(QString surname);
    };
    //...
    
学生类
  • student.h
    //...
    public slots:
        void greeting();//需要在源文件中实现
        void greeting(QString surname);
    };
    //...
    
  • student.cpp
    //...
    void Student::greeting(QString surname) {
        /*
         * QString是带引号的,如果要去除,需要将其转为char *
         * 1、surname.toUtf8() 将QString转为QByteArray
         * 2、.data() 将QByteArray转为char *
         */
        qDebug() << surname.toUtf8().data() << "老师好 ~~ ";
    }
    //...
    
Widget
  • widget.h
#include "widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //传入this,将其放入对象树中
    this->monitor = new ClassMonitor(this);
    this->student = new Student(this);
    
    /*
     * 此时需要通过函数指针来指定函数地址
     * 返回值(作用域::*函数指针名)(参数类型列表) = &作用域::函数名
     */
    void(ClassMonitor::*monitorSignal)(QString) = &ClassMonitor::standUp;
    void(Student::*studentSignal)(QString) = &Student::greeting;
    connect(monitor, monitorSignal, student, studentSignal);
    classBegin();
}

void Widget::classBegin() {
    emit this->monitor->standUp("黄");
}

信号的连接与断开

连接

connect(btn, &QPushButton::clicked, monitor, monitorSingal) //此时无需再调用emit去触发信号

#include "widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->monitor = new ClassMonitor(this);
    this->student = new Student(this);

    //构建无参信号和槽
    void(ClassMonitor::*monitorSignal)() = &ClassMonitor::standUp;
    void(Student::*studentSignal)() = &Student::greeting;
    connect(monitor, monitorSignal, student, studentSignal);

    QPushButton* btn = new QPushButton("上课", this);
    connect(btn, &QPushButton::clicked, monitor, monitorSignal);
    resize(400, 600);

}

Widget::~Widget()
{
}
断开
disconnect(btn, &QPushButton::clicked, monitor, monitorSignal);

连接的对应关系

  • 一个信号可以连接多个槽函数
  • 多个信号可以连接同个槽函数

参数的对应关系

  • 信号函数和槽函数的参数类型必须能对应
  • 信号函数的参数个数可以有多余,但槽函数不可以
    //可以
    void(ClassMonitor::*monitorSignal)(Qstring) = &ClassMonitor::standUp;
    void(Student::*studentSignal)() = &Student::greeting;
    connect(monitor, monitorSignal, student, studentSignal);
    
    //不可以
    void(ClassMonitor::*monitorSignal)() = &ClassMonitor::standUp;
    void(Student::*studentSignal)(Qstring) = &Student::greeting;
    connect(monitor, monitorSignal, student, studentSignal);
    

Qt5之前版本的写法

不推荐使用

优势:参数直观

劣势:不会对参数类型做匹配

无参
connect(monitor, SIGNAL(standUp()), student, SLOT(greeting()));
emit monitor->standUp();
有参
connect(monitor, SIGNAL(standUp(QString)), student, SLOT(greeting(QString)));
emit monitor->standUp("张");

lambda表达式

c++ 11加入的匿名函数对象,用于简化编程

[capture](parameters)mutable -> return-type
{
	//...
}

[capture]

[]标识一个lambda的开始,capture表示函数对象参数

函数对象参数时传递给编译器自动生成的函数对象类的构造函数的

函数对象参数只能使用:当前lambda所在范围内的可见的局部变量(包括lambda所在类的this

函数对象参数的几种形式

  1. 表示没有使用任何函数对象参数
  2. =
    表示lambda函数体内可以使用其所在作用域范围内所有可见的局部变量(包括所在类的this),并且是值传递(相当于编译器自动按值传递的方式传递了所有局部变量)
    QPushButton* btn = new QPushButton("上课", this);
    [=]() {
        btn->setText("上课了"); //如果为空,这里是无法用到btn变量的
    }(); //用()来进行调用
    
  3. &
    =,只不过是用的引用传递的方式(相当于编译器自动按引用传递的方式传递了所有局部变量)
  4. this
    表示函数体内可以使用lambda所在类中的成员变量
  5. a
    表示将指定的局部变量a(其他变量将无法使用)按值传递的方式进行传递,这种方式函数体内不能直接去修改a的拷贝,因为默认时const的,需要先改造a的拷贝构造
  6. &a
    a以引用的方式进行传递
  7. =, &a, &b
    表示ab用引用传递,其余用值传递
  8. &, a, b
    表示ab用值传递,其余用引用传递
使用&可能引起的问题
//点击按钮,改变按钮的文本值
QPushButton *btn = new QPushButton("aaa", this);

/*
 * 当使用信号和槽的使用,其内部会会进入锁状态,即只读,
 * 所以如果使用&引用传递的方式的话可能会出问题
 * 所以一般使用=值传递的方式即可
 */
connect(btn, &QPushButton, this, [&](){
	btn->setText("bbb"); //可能会引起报错
})

mutable

该关键字可以省略

按值传递函数对象参数时,加上mutable关键字之后,可以修改按值传递进来的拷贝(注意是修改拷贝,而非值本身)

/*
 * 操作:先点击a按钮,再点击b按钮
 * 输出:
 *   10
 *   btn1:  20 //因为使用了mutable关键字,所以可以对m进行修改
 *   btn2:  10 //因为是值传递,所以改的其实是拷贝,原值未被修改
 */
QPushButton* btn1 = new QPushButton("a", this);
QPushButton* btn2 = new QPushButton("b", this);
btn2->move(100, 0);
int m = 10;
connect(btn1, &QPushButton::clicked, this, [m]()mutable {
    m = 20;
    qDebug() << "btn1: " << m;
});
connect(btn2, &QPushButton::clicked, this, [=](){
    qDebug() << "btn2: " << m;
});
qDebug() << m;

返回值

-> 返回值类型,如果返回值为void则可以省略

this的省略

对于信号和槽,如果槽函数使用的是lambda的形式,那么如果信号接收者是this的话,可以省略

QPushButton* btn = new QPushButton("点击关闭窗口", this);
connect(btn, &QPushButton::clicked, [=](){
    this->close();
});

QMainWindow

介绍

提供主窗口程序的类,包含一个菜单栏(menu bar)、多个工具栏(tool bars)、多个锚接部件(dock widgets)、一个状态栏(status bar)以及一个中心部件(center widget),是许多应用程序的基础(如文本编辑器、图片编辑器等)

Qt学习笔记_第2张图片

菜单栏

一个窗口中最多只能有一个

#include "mainwindow.h"
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(600, 400);

    //创建一个菜单栏对象
    QMenuBar *bar = menuBar();

    //往菜单栏上添加菜单
    QMenu *fileMenu = bar->addMenu("文件");
    QMenu *editMenu = bar->addMenu("编辑");
    QMenu *viewMenu = bar->addMenu("View");

    //往菜单上添加菜单项
    QAction * newProject = fileMenu->addAction("新建项目");
    //添加一个分割线
    fileMenu->addSeparator();
    QAction * newFile = fileMenu->addAction("新建文件");

    //将菜单栏放入窗口中
    setMenuBar(bar);
}

MainWindow::~MainWindow()
{
}

工具栏

一个窗口中允许有多个

#include "mainwindow.h"
#include 
#include 

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(600, 400);

    //创建一个菜单栏对象
    QMenuBar *bar = menuBar();

    //往菜单栏上添加菜单
    QMenu *fileMenu = bar->addMenu("文件");
    QMenu *editMenu = bar->addMenu("编辑");
    QMenu *viewMenu = bar->addMenu("View");

    //往菜单上添加菜单项
    QAction * newProject = fileMenu->addAction("新建项目");
    //添加一个分割线
    fileMenu->addSeparator();
    QAction * newFile = fileMenu->addAction("新建文件");

    //将菜单栏放入窗口中
    setMenuBar(bar);

    //创建一个工具栏对象
    QToolBar *toolBar = new QToolBar(this);

    //设置可停靠的区域(默认上下左右都可以)
    toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

    //设置浮动性(默认可浮动)
    toolBar->setFloatable(false);

    //往工具栏中放置部件
    toolBar->addAction(newProject);
    //添加分割线
    toolBar->addSeparator();
    toolBar->addAction(newFile);

    //将工具栏放入窗口中(默认放窗口上方)
    addToolBar(Qt::LeftToolBarArea, toolBar); //放到窗口的左侧
}

状态栏

一个窗口最多有一个

#include 
#include 

//...................................

//创建一个状态栏对象
QStatusBar *staBar = statusBar();

//往状态栏中添加部件
QLabel *label1 = new QLabel("label1", this); //存文本标签部件
QLabel *label2 = new QLabel("label2", this);
staBar->addWidget(label1); //从左侧开始添加
staBar->addPermanentWidget(label2); //从右侧开始添加

//将菜单栏放入窗口中
setStatusBar(staBar);

锚接部件与中心部件

锚接部件也叫浮动窗口,可以有多个

中心部件可以是各种形式的部件,如文本编辑部件,最多只能有一个

#include 
#include 

//........................................

//创建一个锚接部件对象
QDockWidget *dock = new QDockWidget("dock1", this);

//设置停靠位置
dock->setAllowedAreas(Qt::TopDockWidgetArea|Qt::RightDockWidgetArea);

//创建和一个文本编辑类的中心部件(中心部件只能有一个)
QTextEdit *edit = new QTextEdit(this);

//将中心部件放入窗口中
setCentralWidget(edit);

//将锚接部件放入窗口中(停靠位置依赖于中心部件)
addDockWidget(Qt::RightDockWidgetArea, dock);

对话框

自定义对话框

自定义对话框可以分为模态对话框和非模态对话框,区别在于对话框期间是否允许对其他的窗口进行操作,其中模态对话框禁止操作

模态对话框

点击新建文件弹出对话框

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->actionfile->setIcon(QIcon(":/image/aaa.png"));
    connect(ui->actionfile, &QAction::triggered, this, [=](){
        QDialog dialog(this); //创建模态对话框对象
        dialog.resize(200, 300); //设置对话框窗口大小
        dialog.exec(); //弹出对话框(该方法会阻塞,所以虽然是栈上创建的对话框对象,创建出来的对话框也不会立马消失)
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}
非模态对话框
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->actionfile->setIcon(QIcon(":/image/aaa.png"));
    
    connect(ui->actionfile, &QAction::triggered, this, [=](){
        //创建非模态对话框对象,不能再创建在栈上,因为lambda直接结束对象消失,会导致对话框窗口一闪而逝
        QDialog* dialog = new QDialog(this);

        //设置对话框窗口大小
        dialog->resize(200, 300);

        /*
         * 由于是创建在堆上,所以对象只有大窗口关闭才会删除,只是关闭对话框不会被删除
         * 所以每次点击都会创建一个对象
         * 通过设置Qt::WA_DeleteOnClose属性,可以使得每次关闭对话框时删除其中的对象
         */
        dialog->setAttribute(Qt::WA_DeleteOnClose);

        //通过show方法弹出的对话框为非模态对话框
        dialog->show();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

系统标准对话框

QColorDialog

选择颜色

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //弹出拾色器并自定义默认选中的颜色
    QColor color = QColorDialog().getColor(Qt::red);
    qDebug() << color.rgb();
    qDebug() << color.red() << color.green() << color.blue();
}

MainWindow::~MainWindow()
{
    delete ui;
}
QFileDialog

选择文件或目录

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    //弹出打开文件窗口并设置默认路径、以及指定文件格式
    //返回:文件全路径
    QString fileName = QFileDialog::getOpenFileName(this, "打开文件", ".", "(*.cpp)");
    qDebug() << fileName;
}

MainWindow::~MainWindow()
{
    delete ui;
}
QFontDialog

选择字体

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    bool flag;
    
    //弹出字体选择框并指定默认字体和字号大小等
    QFont font = QFontDialog::getFont(&flag, QFont("仿宋", 16));
    qDebug() << font.family().toUtf8().data(); //字体
    qDebug() << font.pointSize(); //字号
    qDebug() << font.bold(); //是否有加粗
}

MainWindow::~MainWindow()
{
    delete ui;
}
QInputDialog

允许用户输入一个值,并将其值返回

QMessageBox

模态对话框,常用语显示信息、询问问题等

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
#include 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QMessageBox::critical(this, "错误", "错误对话框");
    QMessageBox::warning(this, "警告", "警告对话框");
    QMessageBox::information(this, "信息", "信息对话框");
    /*
     * 参数4:关联的按钮,默认YES和NO,可自定义
     * 参数5:默认选中的按钮
     * 返回值:选中的按钮放
     */
    QMessageBox::StandardButton res = QMessageBox::question(this, "询问", "询问对话框", QMessageBox::Save|QMessageBox::Cancel, QMessageBox::Save);
    if(res == QMessageBox::Save) {
        qDebug("save");
    } else {
        qDebug("Cancel");
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}
QPageSetupDialog

为打印机提供纸张相关的选项

QPrintDialog

打印机配置

QPrintPreviewDialog

打印预览

QProgressDialog

显示操作过程

widget.ui

布局

Verticl Layout

垂直布局

Horizontl Layout

水平布局

Grid Layout

网格布局,即自动几行几列的排好

按钮

Push Button

普通按钮,可以通过icon属性设置图标

Tool Button

工具按钮,一般用来用作图标按钮

  • QToolButton/toolButtonStyle
    如果想同时显示图标和文字,或者其他显示形式,可以修改此属性
  • QToolButton/autoRaise
    鼠标退出消散按钮(透明)外框,放入则显示 的特效
Radio Button

单选按钮

  • 分组
    默认所有单选项为一组,可通过容器Group Box进行分组
  • 默认选中
    //先设置好单选项的objectname
    ui->btn_man->setChecked(true);
    
  • 选中时输出信息
    connect(ui->btn_woman, &QRasioButton::clicked, [=](){
    	qDebut() << "选中了woman";
    });
    
Check Box

多选按钮

  • 分组
    一样可以用Group Box进行分组
  • 监听选中事件
    默认未开启半选中,通过QCheckBox/tristate属性来开启
    connect(ui->check_item1, &QCheckBox::stateChanged, [=](int state){
    	if (state == 0) qDebug() << "未选中";
    	else if(state == 1) qDebug() << "半选中";
    	else if(state == 2) qDebug() << "选中";
    })
    

Item Widgets

List Widget

以列表的形式来展示内容

#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    /*
     * 一次添加一个列表项:这种方式可以设置对齐方式(默认左对齐)
     */
    QListWidgetItem *item1 = new QListWidgetItem("床前明月光");
    //居中对齐
    item1->setTextAlignment(Qt::AlignCenter);
    QListWidgetItem *item2 = new QListWidgetItem("疑是地上霜");
    //放入ListWidget中
    ui->listWidget->addItem(item1);
    ui->listWidget->addItem(item2);

    /*
     * 一次添加多个列表项:这种方式不能设置对齐方式
     */
    //可以看做是List
    QStringList list;
    list << "举头望明月" << "低头思故乡";
    ui->listWidget->addItems(list);

}

Widget::~Widget()
{
    delete ui;
}

Qt学习笔记_第3张图片

Tree Widget

用树的形式来展示内

#include "widget.h"
#include "ui_widget.h"
#include 
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置头部
    ui->treeWidget->setHeaderLabels(QStringList() << "Hero" << "Hero briefing");

    //设置根结点
    QTreeWidgetItem *powerHeros = new QTreeWidgetItem(QStringList() << "武力" << "法力");
    QTreeWidgetItem *iqHeros = new QTreeWidgetItem(QStringList() << "智力");
    QTreeWidgetItem *speedHeros = new QTreeWidgetItem(QStringList() << "速度");
    //设置二级结点
    QTreeWidgetItem *p1 = new QTreeWidgetItem(QStringList() << "张三丰" << "武力100;法力0");
    QTreeWidgetItem *p2 = new QTreeWidgetItem(QStringList() << "法海" << "武力20;法力90");
    QTreeWidgetItem *i1 = new QTreeWidgetItem(QStringList() << "诸葛亮" << "智力100");
    QTreeWidgetItem *i2 = new QTreeWidgetItem(QStringList() << "孙膑" << "智力95");
    QTreeWidgetItem *s1 = new QTreeWidgetItem(QStringList() << "盗跖" << "速度90");
    QTreeWidgetItem *s2 = new QTreeWidgetItem(QStringList() << "金鹏鸟" << "速度100");
    //将二级结点放入根结点
    powerHeros->addChild(p1);
    powerHeros->addChild(p2);
    iqHeros->addChild(i1);
    iqHeros->addChild(i2);
    speedHeros->addChild(s1);
    speedHeros->addChild(s2);
    //将结点放入树中
    ui->treeWidget->addTopLevelItem(powerHeros);
    ui->treeWidget->addTopLevelItem(iqHeros);
    ui->treeWidget->addTopLevelItem(speedHeros);

}

Widget::~Widget()
{
    delete ui;
}

Qt学习笔记_第4张图片

Table Widget

用表格的形式来展示内

#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置列数
    ui->tableWidget->setColumnCount(3);

    //设置头
    ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "姓名" << "性别" << "年龄");

    //设置行数
    ui->tableWidget->setRowCount(5);

    //设置内容
    QList<QString> names;
    names << "张三" << "李四" << "王五" << "赵六" << "周七";
    QStringList genders;
    genders << "男" << "女" << "男" << "男" << "女";
    for(int i = 0; i < 5; ++i) {
        int col = 0;
        ui->tableWidget->setItem(i, col++, new QTableWidgetItem(names[i]));
        ui->tableWidget->setItem(i, col++, new QTableWidgetItem(genders.at(i)));
        ui->tableWidget->setItem(i, col, new QTableWidgetItem(QString::number(QRandomGenerator::global()->bounded(20, 25))));
    }

}

Widget::~Widget()
{
    delete ui;
}

Qt学习笔记_第5张图片

容器

Group Box

可以给单选按钮、多选按钮进行分组

Scroll Area

滚动条

Tool Box

类似QQ好友分组,通过(对象和类区域中)右键插入页添加分组项

Tab Widget

标签页

Stacked Widget

ui设计界面类似轮播图,内容可以是任意的组件,不过实际使用界面没有轮播按钮,所以一般要配合按钮使用,即点击按钮进入对应的内容页,所以可以理解为是个可纵可横的标签页

#include "widget.h"
#include "ui_widget.h"
#include 

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置默认选项
    ui->stackedWidget->setCurrentIndex(0);

    //绑定点击事件
    connect(ui->btn_tree, &QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(0);
    });
    connect(ui->btn_table, &QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(1);
    });
    connect(ui->btn_list, &QPushButton::clicked, [=](){
        ui->stackedWidget->setCurrentIndex(2);
    });

}

Widget::~Widget()
{
    delete ui;
}
Frame
Widget

可以对放置在里面的部件进行布局

MDI Area
Dock Widget

锚接部件

QAxWidget

Input Widgets

Combo Box

下拉框

ui->comboBox->addItem("选项1");
ui->comboBox->addItem("选项2");
ui->comboBox->addItem("选项3");
//默认选中项
ui->comboBox->setCurrentIndex(0); //或setCurrentText("选项1")
Font Combo Box

字体下拉框

Line Edit

类似标签

Text Edit

类似