学习 QT 过程中的一些笔记

2022-01-12 09:06:46 浏览数 (1)

学习 QT 时候做的一些笔记

目录

  • 目录
  • 按钮常用控件 API
  • QT 窗口体系
  • 信号和槽
    • 点击按钮关闭窗口
    • 自定义信号和槽
    • 当自定义信号和槽出现重载
    • 无参信号和有参信号与槽连接
  • Lambda 表达式
    • 利用 Lambda 表达式实现点击按钮关闭窗口
  • QMainWindow
    • 菜单栏
    • 工具栏
    • 状态栏
    • 标签控件
    • 浮动窗口
    • 核心部件
    • 资源文件
  • 对话框
    • 话框分类:
    • 标准对话框
    • 其他标准对话框
  • 界面布局
  • 控件
    • 按钮组
    • QListWidget 列表容器

按钮常用控件 API

代码语言:javascript复制
QPushButton * btn = new QPushButton;
btn->setParent(this);   // 设置父亲
btn->setText("Hello World");    // 设置文本

QPushButton* btn2 = new QPushButton("Hello World", this);
btn2->move(100, 100);   // 设置位置

resize(800, 300);   // 重置窗口大小

setFixedSize(800, 300); // 固定窗口大小

setWindowTitle("TEST"); // 设置窗口标题

QT 窗口体系

坐标体系:

  • 以左上角为原点
  • 对于嵌套窗口,其坐标是相对于父窗口来说的

信号和槽

点击按钮关闭窗口

代码语言:javascript复制
// 参数1 信号的发送方 参数2 发送的信号(函数地址) 参数3 信号的接收方 参数4 处理的槽函数
connect(btn2, &QPushButton::clicked, this, &QWidget::close);

自定义信号和槽

  • 自定义信号
    • 写到 signals 下
    • 返回值为 void
    • 只需要声明,不需要实现
    • 可以有参数,可以重载
  • 自定义槽
    • 写到 public slot 下
    • 返回值为 void
    • 需要声明,也需要实现
    • 可以有参数,可以重载

teacher.h & teacher.cpp

代码语言:javascript复制
#ifndef TEACHER_H
#define TEACHER_H

#include <QObject>

class Teacher : public QObject
{
    Q_OBJECT
public:
    explicit Teacher(QObject *parent = nullptr);

signals:
    // 自定义信号
    // 返回值为void, 只需要声明, 不需要实现
    // 可以有参数, 可以重载

    void hungry();

public slots:
};

#endif // TEACHER_H

/*--------------------------------------------------------------*/
#include "teacher.h"

Teacher::Teacher(QObject *parent) : QObject(parent)
{

}

student.h & studemt.cpp

代码语言:javascript复制
#ifndef STUDENT_H
#define STUDENT_H

#include <QObject>

class Student : public QObject
{
    Q_OBJECT
public:
    explicit Student(QObject *parent = nullptr);

signals:

public slots:
    // 槽函数
    // 返回值为void, 需要声明, 也需要实现
    // 可以有参数, 可以发生重载

    void treat();
};

#endif // STUDENT_H

/*--------------------------------------------------------------*/
#include "student.h"
#include <QDebug>

Student::Student(QObject *parent) : QObject(parent)
{

}

void Student::treat()
{
    qDebug() << "请老师吃饭";
}

widget.h & widget.cpp

代码语言:javascript复制
#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* t;
    Student* s;

    void classOver();
};
#endif // WIDGET_H

/*--------------------------------------------------------------*/
#include "widget.h"
#include "ui_widget.h"

// Teracher类
// Student类
// 下课后, 老师会触发一个信号, 饿了, 学生响应信号, 请吃饭

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

    this->t = new Teacher(this);
    this->s = new Student(this);

    connect(t, &Teacher::hungry, s, &Student::treat);

    classOver();
}

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

void Widget::classOver()
{
    // 下课函数, 触发老师饿了的信号
    emit t->hungry();
}

当自定义信号和槽出现重载

  • 利用函数指针 明确指向函数地址
    • void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry;
    • void(Student:: *studentSlot)(QString) = &Student::treat;
  • QString 转成 char*
    • .toutf8 () 转为 QByteArray
    • .Data () 转为 Char*

无参信号和有参信号与槽连接

代码语言:javascript复制
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->resize(600, 400);

    this->t = new Teacher(this);
    this->s = new Student(this);

    QPushButton *btn_1 = new QPushButton("有参信号和槽连接", this);
    QPushButton *btn_2 = new QPushButton("无参信号和槽连接", this);
    btn_2->move(200,0);

    // 有参信号和槽连接
    void(Teacher:: *teacherSignal_1)(QString) = &Teacher::hungry;
    void(Student:: *studentSlot_1)(QString) = &Student::treat;

    connect(t, teacherSignal_1, s, studentSlot_1);
    connect(btn_1, &QPushButton::clicked, this, &Widget::classOver);


    // 无参信号和槽连接
    void(Teacher:: *teacherSignal_2)(void) = &Teacher::hungry;
    void(Student:: *studentSlot_2)(void) = &Student::treat;

    connect(t, teacherSignal_2, s, studentSlot_2);
    connect(btn_2, &QPushButton::clicked, t, teacherSignal_2);

    // disconnect断开信号
//    disconnect(btn_2, &QPushButton::clicked, t, teacherSignal_2);
}

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

void Widget::classOver()
{
    // 下课函数, 触发老师饿了的信号
    emit t->hungry("shit");
}

扩展

  • 信号是可以连接信号的
  • 一个信号可以连接多个槽函数
  • 多个信号 可以连接 同一个槽函数
  • 信号和槽函数的参数 类型必须一一对应
  • 信号的参数个数 可以多于槽函数的参数个数
  • disconnect 断开信号
代码语言:javascript复制
// 信号和槽函数的参数 类型必须一一对应
void(Teacher:: *teacherSignal_1)(int) = &Teacher::hungry;
void(Student:: *studentSlot_1)(int) = &Student::treat;

// 一个信号可以连接多个槽函数
QPushButton *btn_3 = new QPushButton("同时与槽连接", this);
btn_3->move(0, 50);
connect(btn_3, &QPushButton::clicked, this, &Widget::classOver);
connect(btn_3, &QPushButton::clicked, t, teacherSignal_2);

// 信号的参数个数 可以多于槽函数的参数个数
void(Teacher:: *teacherSignal_1)(QString, int) = &Teacher::hungry;
void(Student:: *studentSlot_1)(QString) = &Student::treat;

// disconnect断开信号
disconnect(btn_2, &QPushButton::clicked, t, teacherSignal_2);

Lambda 表达式

[](){}

  • 函数对象参数 [ ]
    • = 值传递 推荐使用值传递
    • & 引用传递
    • this
    • a 按 a 值传递,即只能看到 a
    • a, &b 将 a 按值传递,b 按引用传递
    • =, &a, &b 除 a 和 b 按引用进行传递外,其他参数都按值传递
    • &, a, b 除 a 和 b 按值进行传递外,其他参数都按引用传递
  • 操作符重载函数参数 ( )
    • 参数可以通过按值 (如: (a, b)) 和按引用 (如: (&a, &b)) 两种方式传递
  • 可修改标示符
    • mutable 声明,加上 mutable 修饰符后,可以修改按值传递进来的拷贝 (修改的是拷贝,不是本体)
  • 函数返回值
    • int ret = []()->int{return 100;}();
代码语言:javascript复制
/*
= 值传递 推荐使用值传递
& 引用传递
this
a 按a值传递, 即只能看到a
a, &b 将a按值传递, b按引用传递
=, &a, &b 除a和b按引用进行传递外, 其他参数都按值传递
&, a, b 除a和b按值进行传递外, 其他参数都按引用传递
*/

[=](){
    bin->setText("aaaa");
}();	// 值传递和引用传递都可以修改成功, ();是函数调用, 前面是函数声明

QPushButton *btn_1 = new QPushButton(this);
QPushButton *btn_2 = new QPushButton(this);
btn_2->move(100, 0);
int m = 10;

// 输出110, 不加mutable会报错, 但是修改的是m的拷贝, 不是本体
connect(btn_1, &QPushButton::clicked, this, [m]()mutable{m = 100   10; qDebug() << m;});
connect(btn_2, &QPushButton::clicked, this, [=](){qDebug() << m;}});	// 输出10

利用 Lambda 表达式实现点击按钮关闭窗口

代码语言:javascript复制
QPushButton *btn_1 = new QPushButton("关闭", this);
connect(btn_1, &QPushButton::clicked, this, [](){
    this->close();
});

QPushButton *btn_2 = new QPushButton("关闭", this);
connect(btn_2, &QPushButton::clicked, this, [=](){
    emit t->treat("屎");
});

QMainWindow

菜单栏

代码语言:javascript复制
// 菜单栏 最多有一个
QMenuBar* bar = menuBar();
setMenuBar(bar);

// 创建菜单栏
QMenu* fileMenu = bar->addMenu("文件");
QMenu* editMenu = bar->addMenu("编辑");

// 创建菜单项
QAction* newAction = fileMenu->addAction("新建");
// 添加分隔线
fileMenu->addSeparator();
QAction* openAction = fileMenu->addAction("打开");
QAction* pasteAction = editMenu->addAction("粘贴");

工具栏

代码语言:javascript复制
// 工具栏 可以有多个
QToolBar* toolBar = new QToolBar(this);
addToolBar(Qt::BottomToolBarArea, toolBar);	// 默认左右停靠

// 设置只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);

// 设置浮动
toolBar->setFloatable(false);

// 设置移动 总开关
toolBar->setMovable(false);

// 工具栏中设置内容
toolBar->addAction(newAction);
toolBar->addSeparator();
toolBar->addAction(openAction);

状态栏

代码语言:javascript复制
// 状态栏 最多有一个
QStatusBar* stBar = statusBar();
setStatusBar(stBar);

标签控件

代码语言:javascript复制
// 放标签控件 可以多个
QLabel* label_1 = new QLabel("提示信息", this);
stBar->addWidget(label_1);

QLabel* label_2 = new QLabel("右侧提示信息", this);
stBar->addPermanentWidget(label_2);

浮动窗口

代码语言:javascript复制
// 铆接部件 浮动窗口 可以多个
QDockWidget* dockWidget = new QDockWidget("浮动窗口", this);
addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
// 设置只允许上下停靠
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);

核心部件

代码语言:javascript复制
// 设置核心部件 最多有一个
QTextEdit* edit = new QTextEdit();
setCentralWidget(edit);

资源文件

  • 将文件拷贝到项目位置下
  • 右键项目 添加新文件 -> Qt -> Qt recourse File -> 给资源文件起名
  • res 生成 res.qrc
  • open in editor
  • 添加前缀
  • 添加文件
  • 使用 “: 前缀名 文件名”

对话框

话框分类:

  • 模态对话框 (不可以对其他窗口进行操作)
  • 非模态对话框 (可以对其他窗口进行操作)
代码语言:javascript复制
// 点击新建按钮新建一个对话框
connect(ui->actionnew, &QAction::triggered, [=](){
    // 模态对话框创建
    QDialog dlg_1(this);
    dlg_1.resize(200,100);
    dlg_1.exec();

    // 非模态对话框创建
    QDialog *dlg_2 = new QDialog(this);
    dlg_2->resize(500,200);
    dlg_2->show();
    dlg_2->setAttribute(Qt::WA_DeleteOnClose);  // 关闭的时候就释放
});

标准对话框

  • 错误对话框
  • 信息对话框
  • 提问对话框
  • 警告对话框

参数 1

参数 2

参数 3

参数 4

参数 5

父类

标题

显示内容

按键类型

默认关联回车按键

返回值:也是 StandardButton 类型,利用返回值判断用户选择

代码语言:javascript复制
// 错误对话框
QMessageBox::critical(this, "critical", "错误");

// 信息对话框
QMessageBox::information(this, "info", "信息");

// 提问对话框
// 参数1 父类 参数2 标题 参数3 提示内容 参数4 按键类型 参数5 默认关联回车按键
if(QMessageBox::Save == QMessageBox::question
        (this, "ques", "提问", QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))
{
     qDebug() << "选择的是保存";
}
else
{
    qDebug() << "选择的是取消";
}

// 警告对话框
QMessageBox::warning(this, "warning", "警告");

其他标准对话框

  • 颜色对话框
  • 文件对话框
  • 字体对话框
代码语言:javascript复制
// 颜色对话框
QColor color = QColorDialog::getColor(QColor(255,0,0));
qDebug() << color.red() << color.green() << color.blue();

// 文件对话框
// 参数1 父类 参数2 标题 参数3 默认打开路径 参数4 过滤文件格式
// 返回值为打开文件的路径
QString str = QFileDialog::getOpenFileName(this, "打开文件", "C:\Users\17740\Desktop\", "(*.txt)");
qDebug() << str;

// 字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag, QFont("微软雅黑", 20));
qDebug() << font.family().toUtf8().data() << font.pointSize() << font.bold() << font.italic();

界面布局

  • 实现登录窗口
  • 利用布局方式 给窗口进行美化
  • 选取 widget 进行布局 水平布局、垂直布局、栅格布局
  • 给用户名、密码、登录、退出按钮进行布局
  • 默认窗口和控件之间有间隙,可以调整 layout
  • 利用弹簧进行布局

控件

按钮组

  • QPushBotton 常用按钮
  • QToolButton 工具按钮 用于显示图片,如果想显示文字,修改风格:toolButtonStyle,透明风格 autoRaise
  • radioButton 单选按钮,设置默认 ui->rBtnMan->setChecked (true);
  • checkbox 多选按钮,监听状态,0 未选中,1 半选中,2 选中

QListWidget 列表容器

  • QListWidget* item = new QListWidgetItem(“hello”);
  • ui->listWidget->addItem(item);
  • 设置居中方式 item->setTextAlignment (Qt::AlignHCenter);
  • 可以利用 addItems 一次性添加多个内容

0 人点赞