Qt入门笔记
目录
一、前言
二、创建Qt项目
2.1、使用向导创建
2.2、最简单的Qt应用程序
2.2.1、main函数
2.2.2、widget.h文件
2.2.3、widget.cpp文件
2.3、Qt按键Botton
2.3.1、创建一个Botton
2.3.2、信号与槽
2.3.3、按键使用信号与槽的方法
2.4、文件Read与Write-QFile类
2.4.1、文件操作——Read文件
2.4.2、文件操作——Write文件
2.4.3、QTextStream读写文件
1、QTextStream方式读文件
2、QTextStream方式写文件
2.4.4、光标操作seek
2.5、文件选择对话框 QFileDialog类
2.5.1、显示单(多)个对话框
2.5.2、另存(创建)文件
2.5.3、显示单个对话框的另一种方式
2.6、文本text-textEdit类
2.6.1、textEdit的信号
2.6.2、QList
2.6.3、ExtraSelection(文本字体颜色属性)
2.7、QComboBox选择条框
2.8、消息对话框QMessageBox
2.9、快捷键添加-QShortcut
2.10、QT事件
2.10.1、利用事件制作自定义按键
2.10.2、自定义按键信号与槽
2.10.3、事件实现控制字体大小
一、前言
这个是用于学习QT入门的一个笔记。使制作一个QT小项目——记事本,所需要掌握的东西。逐渐熟悉每个类的基本用法,暴干2W多字,以后会继续更新!
二、创建Qt项目
2.1、使用向导创建
打开Qt Creator界面选择菜单栏[文件]新建工程
弹出New Project对话框,选择Qt Widgets Application
点击Choose
下一步默认即可
选择编译套件
向导会默认添加一个继承自QMainWindow的类,可以在此修改类的名字和基类。默认的基类有QMainWindow、QWidget以及QDialog三个,我们可以选择QWidget(类似于空窗口),这里我们可以先创建一个不带UI的界面,继续下一步。后面的默认即可
2.2、最简单的Qt应用程序

2.2.1、main函数
#include "mainwindow.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow w;w.show();//相当于绘制函数,没有它窗口都看不见return a.exec();//用来启动应用程序的事件循环的。当你调用这个函数时,它会开始处理和分发事件,如用户的点击、键盘输入等
}
- MainWindow:这是一个包含完整菜单栏、工具栏和状态栏的主窗口应用程序框架。它适合于更复 杂的应用程序,需要这些额外的用户界面元素来提供丰富的功能和交互
- Widget:这通常是一个简单的窗口,没有内置的菜单栏、工具栏或状态栏。它适合于更简单或专用 的应用程序,不需要复杂的用户界面组件。
- QApplication a(argc, argv); 这行代码的作用是创建一个 QApplication 类的实例。这是几乎每个 Qt 应用程序必须做的第一步,因为它负责管理应用程序的许多核心功能。
2.2.2、widget.h文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget //MainWindow公有继承QMainWindow,QMainWindow继承Q_OBJECT
{Q_OBJECT//一个宏,继承Q_OBJECT或者集成它的子类需要加上public:Widget(QWidget *parent = nullptr);//构造函数~Widget();//析构函数private:Ui::Widget *ui;
};
#endif // WIDGET_H
2.2.3、widget.cpp文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)//初始化列表
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}
- Widget::Widget(QWidget *parent) : QWidget(parent),ui(new Ui::Widget):代码 : QWidget(parent) 是初始化列表,用于调用基类 QWidget 的构造函数,并将 parent 传递给 它。 ui(new Ui::Widget) 是初始化类内部的 ui 成员变量,这是通过 new 关键字动态分配的。 Ui::Widget 是由 Qt Designer 工具生成的,用于处理用户界面。这种方式允许将用户界面的设计与后端 逻辑代码分离,有助于提高代码的可维护性和可读性。
2.3、Qt按键Botton
2.3.1、创建一个Botton
在Qt中创建一个按键是非常容易得事,只需要随便拖拖拉拉就可以了
我们可以修改它的按键颜色以及不同状态下(按下、点击......)的属性,比如颜色
这里修改为黑色做个示例:
这个就是修改后的样子
我们还可以修改按键不同状态下的颜色以及他的“外表”,我们就需要用到一点语法:
这里我们就是用照片来美化按键的UI

先把照片放在一个文件夹里面,然后copy去工程文档里面,然后回到编辑,右键选择添加文件:

然后选择Qt里面的Resource File,一路默认会出现一下界面:
然后依次点击:
然后把照片全部添加进去:

这里点击添加资源,选择对应要使用的照片即可,配合使用的语法:
QPushButton{border-image: url(:/icon/s1.png);}//默认状态为s1照片
QPushButton:hover{border-image: url(:/icon/s2.png);}//悬停状态为s2照片
QPushButton:pressed{border-image: url(:/icon/s3.png);}//按下状态为s3照片
2.3.2、信号与槽
简单来说信号就是触发槽,槽是一个执行的动作,信号就是触发槽的信号。
- 信号 (Signals) :是由对象在特定事件发生时发出的消息。例如, QPushButton 有一个clicked() 信号,当用户点击按钮时发出。
- 槽 (Slots) :是用来响应信号的方法。一个槽可以是任何函数,当其关联的信号被发出时,该槽函数 将被调用。
简单使用一下信号与槽:我们需要在类Widget中添加一下信号和槽的成员:
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();//类成员信号定义
signals:void mysignal();//无参类型信号void mysignalparams(int value);//有参类型信号//类成员槽定义
private slots:void myslot();//无参类型槽void myslotparams(int value);//有参类型槽private:Ui::Widget *ui;
};
然后在.cpp文件中定义槽的函数:
//槽函数定义
void Widget::myslot()
{std::cout << "myslot" << std::endl;
}
//槽函数定义
void Widget::myslotparams(int value)
{std::cout << "myslotparams" << std::endl;std::cout << value << std::endl;
}
然后将信号和槽“连接起来(connect)”:
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(this,SIGNAL(mysignal()),this,SLOT(myslot()));//将信号和槽联系起来connect(this,SIGNAL(mysignalparams(int)),this,SLOT(myslotparams(int)));//将信号和槽联系起来//代码触发信号emit mysignal();emit mysignalparams(99);
}
运行结果:
2.3.3、按键使用信号与槽的方法
方法一共有4种:
- Designer 中点击:
- 使用 QObject::connect(是否使用函数指针)
- 使用 C++11 Lambda表达式
第一种:右键点击按键,选择转到槽:

然后就会自动跳转到.cpp文件中:我们定义好槽的函数内容即可
// 第一种方式按键响应函数
void MainWindow::on_pushButton_clicked()
{std::cout << "第一种方法按下响应" << std::endl;
}
第二种:使用 QObject::connect(是否使用函数指针)
我们需要在.h头文件中声明槽,第一种系统会自动帮我们声明
然后我们也是去.cpp文件中定义内容并且使用connect函数“连接” 信号与槽
第四种: 使用C++11 Lambda表达式
优点:不需要在头文件中声明槽函数
//第三方式:lambda表达式:QObject::connect(sender, &Sender::signal, [=]() { /* lambda body */ });QObject::connect(ui->pushButton_3, &QPushButton::clicked,[=](){std::cout << "第三种方法按下响应" << std::endl;});//不需要在h头文件中声明槽——响应函数
运行结果:依次点击按键,依次执行对应的槽函数,依次打印:
2.4、文件Read与Write-QFile类
- open() :打开一个文件。需要指定模式(如只读、只写、读写等)。
- close() :关闭文件
- read() 和 write() :用于读取和写入数据。
- exists() :检查文件是否存在。
- remove() :删除文件。
- copy() :复制文件。
open(open_mode);
返回值:失败返回0,成功返回1open_mode:
QIODevice::NotOpen
QIODevice::ReadOnly//只读
QIODevice::WriteOnly//只写
QIODevice::ReadWrite//可读可写
QIODevice::Append
QIODevice::Truncate
QIODevice::Text//文本,\n默认修改为\r\n更好阅读
QIODevice::Unbuffered
QIODevice::NewOnly
QIODevice::ExistingOnly
这里的函数和Linux系统编程的函数大差不差,可以稍微参考一下:Linux系统编程
2.4.1、文件操作——Read文件
//点击按键读取函数
void Widget::on_pushButton_clicked()
{//1.打开文件//QFile file("D:/Qt/test.txt");//需要打开的文件的位置QFile file;file.setFileName("D:/Qt/test.txt");if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//打开失败{qDebug() << "open File error";}else{qDebug() << "open File success";}//2.读取文件char buf[100] = {'\0'};qint64 Read_count = 0;Read_count = file.read(buf, 100);if(Read_count != 0)// 读取成功返回读取到的字节数{std::cout << "Read :" << Read_count << std::endl;}else{std::cout << "Read error" << std::endl;}//3.输出文件内容qDebug() << buf;//输出文件内容//4.关闭文件file.close();
}
2.4.2、文件操作——Write文件
//点击按键写入函数
void Widget::on_pushButton_2_clicked()
{//1.打开文件//QFile file("D:/Qt/test.txt");QFile file;file.setFileName("D:/Qt/test.txt");file.open(QIODevice::WriteOnly | QIODevice::Text);//文件不存在会自动创建,文件存在会更换带掉其内容//2.写入文件file.write("Hello BOBEN!");//返回写入的数据的个数//3.关闭文件file.close();
}
Read和Write文件运行结果:
2.4.3、QTextStream读写文件
1、QTextStream方式读文件
//QTextStream方式读取文件槽
void Widget::on_pushButton_clicked()
{QFile file;file.setFileName("D:/Qt/test.txt");//需要打开的文件的存放位置if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//只读文本模式打开失败{qDebug() << "file open error";}QTextStream in(&file);//绑定文件in.setCodec("UTF-8");//设置字符// QString context = in.read(file.size());//一次性全部读取内容while(!in.atEnd())//分行读取 in.atEnd()——确认是否到文件底部,到了返回1,没有到返回0{QString context = in.readLine();//读取一行内容qDebug() << context;//打印一行内容qDebug() << "----";//打印一行内容}file.close();//关闭文件
}
2、QTextStream方式写文件
//QTextStream方式写入文件槽
void Widget::on_pushButton_2_clicked()
{QFile file;file.setFileName("D:/Qt/test.txt");//文件路径,不存在自动创建if(!file.open(QIODevice::WriteOnly | QIODevice::Text))文件不存在会自动创建,文件存在会更换带掉其内容{qDebug() << "file open error";}QTextStream out(&file);out.setCodec("UTF-8");out << "nihao Boben";file.close();
}
2.4.4、光标操作seek
这里的光标和我们电脑的光标实质上是一样的,可以理解为光标在哪里,文本就从那里开始操作(读 | 写):
这里创造两个按键,并且都有自己的信号(点击)与槽,一个按键打开文件后读取函数(一行一行读取),读取完后不关闭文件,注意读取完后光标就处于文本的最后的地方了,如前面所说:可以理解为光标在哪里,文本就从那里开始操作(读 | 写),另一个按键则不需要打开文件了,可以直接读取内容,但是这个时候光标就处于文本的最后的地方,所以按键2根本读取不到内容,运行结果在后面!
.h文件
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();QFile file;//将文本的QFile类作为成员使用private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();void on_pushButton_3_clicked();private:Ui::Widget *ui;
};
#endif // WIDGET_H.c文件
//QTextStream方式读取文件槽
void Widget::on_pushButton_clicked()
{//QFile file;file.setFileName("D:/Qt/test.txt");//需要打开的文件的存放位置if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//只读文本模式打开失败{qDebug() << "file open error";}QTextStream in(&file);//绑定文件in.setCodec("UTF-8");//设置字符// QString context = in.read(file.size());//一次性全部读取内容while(!in.atEnd())//分行读取 in.atEnd()——确认是否到文件底部,到了返回1,没有到返回0{QString context = in.readLine();//读取一行内容qDebug() << context;//打印一行内容qDebug() << "----";//打印一行内容}//file.close();//关闭文件
}void Widget::on_pushButton_3_clicked()
{//file.setFileName("D:/Qt/test.txt");//需要打开的文件的存放位置//if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//只读文本模式打开失败//{// qDebug() << "file open error";//}QTextStream in(&file);//绑定文件in.setCodec("UTF-8");//设置字符// QString context = in.read(file.size());//一次性全部读取内容while(!in.atEnd())//分行读取 in.atEnd()——确认是否到文件底部,到了返回1,没有到返回0{QString context = in.readLine();//读取一行内容qDebug() << context;//打印一行内容qDebug() << "----";//打印一行内容}file.close();//关闭文件
}
运行结果:
这个时候就需要使用光标移动函数了:
seek(pace); pace:光标位置
所以我们只需要在按键2读取前加上一句代码可以让它可以读取到内容:
void Widget::on_pushButton_3_clicked()
{//file.setFileName("D:/Qt/test.txt");//需要打开的文件的存放位置//if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//只读文本模式打开失败//{// qDebug() << "file open error";//}QTextStream in(&file);//绑定文件in.setCodec("UTF-8");//设置字符// QString context = in.read(file.size());//一次性全部读取内容file.seek(0);while(!in.atEnd())//分行读取 in.atEnd()——确认是否到文件底部,到了返回1,没有到返回0{QString context = in.readLine();//读取一行内容qDebug() << context;//打印一行内容qDebug() << "----";//打印一行内容}file.close();//关闭文件
}
运行结果:
2.5、文件选择对话框 QFileDialog类
文件选择对话框就是和我们的电脑点开文件夹出现的窗口一样,类似于:
2.5.1、显示单(多)个对话框
qfileDialog.setFileMode(File_mode);

示例:
//浏览文件夹槽函数
void Widget::on_pushButton_clicked()
{QFileDialog qfileDialog;// 创建一个 QFileDialog 实例qfileDialog.setFileMode(QFileDialog::ExistingFile);// 设置对话框为打开文件模式ExistingFile(s),复数为可以打开多个文件qfileDialog.setNameFilter("*.txt");// 设置文件过滤器//其他使用过滤器:dialog.setNameFilter("Text files (*.txt);;Images (*.png *.jpg);;All files(*)");qfileDialog.exec();// 显示对话框QStringList qstrings = qfileDialog.selectedFiles();//返回选中的文件的位置for(QString str : qstrings)//链表遍历打印{qDebug() << str;//打印选中的文件位置}
}
运行结果:
2.5.2、另存(创建)文件
//另存文件槽函数
void Widget::on_pushButton_2_clicked()
{QString fileName = QFileDialog::getSaveFileName(this,tr("Save File"),"D:/QT/man.txt");QFile file;file.setFileName(fileName);//文件路径,不存在自动创建if(!file.open(QIODevice::WriteOnly | QIODevice::Text))//打开文件{qDebug() << "file open error";}QTextStream out(&file);out.setCodec("UTF-8");out << "666666666";file.close();
}
运行结果:
就会得到一个新的.txt文件:
2.5.3、显示单个对话框的另一种方式
QString fileName = QFileDialog::getOpenFileName(this,tr("Open File"),"D:/QT/",tr("Text(*.txt)"));
2.6、文本text-textEdit类
制作一个文本输入框一样很简单,也只需要和按键一样一拖即可实现:
上面我们打开文件读取文件内容是将内容打印出来,这里我们可以打印出来在文本上: 那我们就先要学习几个textEdit类里面简单的函数 :
ui->textEdit->clear();//清除textEdit的内容
ui->textEdit->setText(context);//在文本上显示出来(替换形式)
ui->textEdit->append(context);//在文本上显示出来(追加形式)
context属于QString类型
然后我们就可以使用这几个函数和前面所学的实现,点击按键,跳出一个文件选择框,选择好文件后,将文件的内容显示在文本框中:
//打开文件按键的槽函数
void Widget::on_pushButton_clicked()
{//返回选中文件的文件路径QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"),"D:/Qt/",tr("Text (*.txt)"));QFile file;//定义一个QFile类定义一个文件//ui->textEdit->clear();//清除textEdit的内容file.setFileName(fileName);if(!file.open(QIODevice::ReadOnly | QIODevice::Text))//打开文件{qDebug() << "file open error";//打开文件失败打印信息}QTextStream in(&file);//使用QTextStream读取文件内容in.setCodec("UTF-8");//用UTF-8字符格式读取while(!in.atEnd()){QString context = in.readLine();// qDebug() << qPrintable(context);ui->textEdit->setText(context);//ui->textEdit->append(context);//在文本上显示出来}
}
2.6.1、textEdit的信号
我们到UI界面右击文本,点击跳到槽,可以看看它有什么信号:
这里使用上面这个箭头的作为演示,实现打印当前第几行第几列的功能:
//文本当前位置坐标发生变化信息所触发的槽
void Widget::on_textEdit_cursorPositionChanged()
{QTextCursor cursor = ui->textEdit->textCursor();//获取当前新的坐标//qDebug() << cursor.blockNumber()+1 <<","<< cursor.columnNumber() + 1;QString blockNum = QString::number(cursor.blockNumber()+1);//提取坐标中的列坐标QString columnNum = QString::number(cursor.columnNumber()+1);//提取坐标中的行坐标qDebug() << blockNum << columnNum;//打印信息
}
2.6.2、QList
- 数组式存储 : QList 在大多数情况下使用连续内存存储其元素,类似于数组。这意味着它提供了快 速的索引访问(通过下标操作符 [] ),以及相对高效的迭代性能。
- 动态调整大小:与静态数组不同, QList 可以动态增长和缩减,自动管理内存分配。
- 链表特性:虽然 QList 主要基于数组,但它也提供了一些链表的操作,比如在列表的开始或结束 处添加和移除元素。这些操作通常比在数组中间插入或删除元素更高效。
- 复制时共享内存 : QList 使用一种称为 “ 隐式共享 ” ( implicit sharing )或 “ 写时复制 ” ( copy-onwrite)的技术。这意味着当你复制一个 QList 时,它不会立即复制所有元素,而是共享相同的数 据,直到你尝试修改其中一个列表,此时才进行实际的复制。这使得复制 QList 变得非常高效。
基本用法:
包含头文件:首先,你需要包含 QList 的头文件。
#include <QList>
创建 QList 实例:创建一个 QList 对象,并指定存储的元素类型。
QList<int> list;
添加元素:使用 append 或 push_back 方法添加元素。
list.append(1);
list.append(2);
list.append(3);
访问元素:可以使用下标操作符或 at() 方法访问元素。
int firstElement = list[0];
int secondElement = list.at(1);
遍历列表:使用迭代器或范围基的 for 循环遍历列表。
for(int i = 0; i < list.size(); ++i)
{ // size = sizeof(arr)/sizeof(arr[0])qDebug() << list[i];
}
// 或者使用范围基的 for 循环
for(int item : list)
{qDebug() << item;
}
移除元素:使用 removeAt 、 removeOne 或 clear 方法移除元素。
list.removeAt(1); // 移除索引为 1 的元素
list.removeOne(3); // 移除一个值为 3 的元素
list.clear(); // 清空整个列表
2.6.3、ExtraSelection(文本字体颜色属性)
如何工作:
- ExtraSelection 结构体 : QTextEdit::ExtraSelection 是一个结构体,包含了两个主要成员:QTextCursor 和 QTextCharFormat 。 QTextCursor 表示在文本中的一个位置或者区间,而QTextCharFormat 用于定义这个区间的格式,比如背景颜色、字体等。
- 设置 ExtraSelection :你可以创建一个或多个 ExtraSelection 对象,为它们设置相应的光标位 置和格式,然后通过 QTextEdit 的 setExtraSelections 方法将这些对象应用到文本编辑器中。 这样,你可以对文本的特定部分应用特定的格式,而不影响其他文本。
- 高亮当前行 :要高亮显示当前行,你需要在 cursorPositionChanged() 信号的槽函数中创建一个 ExtraSelection 对象。使用当前的 QTextCursor 对象(通过 textCursor() 方法获取)来确定当前行的位置,并设置背景颜色为你选择的高亮颜色。
这里先使得文本当前行高光作为例子:
//文本当前位置坐标发生变化信息所触发的槽
void Widget::on_textEdit_cursorPositionChanged()
{QTextCursor cursor = ui->textEdit->textCursor();//获取当前新的坐标//qDebug() << cursor.blockNumber()+1 <<","<< cursor.columnNumber() + 1;QString blockNum = QString::number(cursor.blockNumber()+1);//提取坐标中的列坐标QString columnNum = QString::number(cursor.columnNumber()+1);//提取坐标中的行坐标qDebug() << blockNum << columnNum;//打印信息//设置当前高亮QList<QTextEdit::ExtraSelection> extraSelection;//制作一个QTextEdit::ExtraSelection类型的容器QTextEdit::ExtraSelection ext;//声明一个结构体//1、知道当前行ext.cursor = ui->textEdit->textCursor();QBrush qBrush(Qt::yellow);//2、调制颜色ext.format.setBackground(qBrush);ext.format.setProperty(QTextFormat::FullWidthSelection, true);//3、设置extraSelection.append(ext);//将结构体假如到容器里面去ui->textEdit->setExtraSelections(extraSelection);//设置}
不仅有背景颜色的更改,还有更多其他的属性可以更改:
这里使用改变字体大小来作为一个示例:
//快捷键槽函数
void Widget::test()
{qDebug() << "test";//获取当前字体的信息QFont font = ui->textEdit->font();//获取字体大小int fontsize = font.pointSize();if(fontsize == -1) return;//改变字体大小int newsize = fontsize +1;font.setPointSize(newsize);//设置字体大小ui->textEdit->setFont(font);
}
运行结果,触发槽后字体逐渐变大:

2.7、QComboBox选择条框
接下来还是老样子,连接信号与槽,声明和定义槽:
.c文件
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//这里使用选中框变化的信号currentIndexChanged(int index) index选中内容的索引(从0开始)connect(ui->comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(oncurrentIndexChanged(int)));//连接信号与槽
}Widget::~Widget()
{delete ui;
}//槽函数执行动作
void Widget::oncurrentIndexChanged(int index)
{qDebug() << index;qDebug() << ui->comboBox->currentText();//这里需要展现的内容都可以去手册查,看看自己需要什么,这里是打印选中的文本//ui->comboBox->currentText();这里返回的是Qstring类型//想要转换成const char*类型需要ui->comboBox->currentText().toStdString().c_str;
}.h文件
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void oncurrentIndexChanged(int index);//声明槽函数private:Ui::Widget *ui;
};
#endif // WIDGET_H
运行结果:
2.8、消息对话框QMessageBox
- 显示信息 :向用户显示一些信息性的消息。
- 询问用户决策 :询问用户一个问题,并根据其回答做出相应的操作。
- 报告错误 :向用户报告程序运行中的错误。
消息对话框到底是啥样的呢? 
那我们怎么才能创建生成一个对话框呢?我们可以打开手册查看这个类的成员用法:
这里还是使用一个按键来触发制作一个对话框:
//弹出对话框的按键的槽
void Widget::on_pushButton_clicked()
{int ret = QMessageBox::warning(this, tr("My Application"),//对话框标题tr("The document has been modified.\n""Do you want to save your changes?"),QMessageBox::Save | QMessageBox::Discard| QMessageBox::Cancel);//按键的名字switch (ret) //哪个按键按下了{case QMessageBox::Save:// Save was clickedqDebug() << "Save";break;case QMessageBox::Discard:// Don't Save was clickedqDebug() << "Discard";break;case QMessageBox::Cancel:// Cancel was clickedqDebug() << "Cancel";break;default:// should never be reachedbreak;}
}
运行结果:
2.9、快捷键添加-QShortcut
// 创建一个快捷键 (Ctrl + N) 并关联到窗口
QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+N"), &window);
// 当快捷键被按下时,显示一个消息框
QObject::connect(shortcut, &QShortcut::activated, [&]()
{QMessageBox::information(&window, "Shortcut Activated", "Ctrl+N waspressed");
}); 我们可以看看QKeySequence函数里面的成员可以是什么,手册里面实在太多了,我们只看一部分好了:发现快捷键还可以操作文件,下面我们来写一个例子:
这里我们也写一个简单的例子,快捷键触发槽函数打印信息:
.c文件
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QShortcut *shortcut = new QShortcut(QKeySequence("Ctrl+N"), this);//创建一个快捷键connect(shortcut,SIGNAL(activated()),this,SLOT(test()));//绑定信号与槽
}Widget::~Widget()
{delete ui;
}//快捷键槽函数
void Widget::test()
{qDebug() << "test";
}.h文件
class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void test();//槽函数声明private:Ui::Widget *ui;
};
#endif // WIDGET_H 运行结果:
对于要对文件进行操作的话,我们需要在参数方面进行修改:
QShortcut *shortcut = new QShortcut(QKeySequence(tr("Ctrl+S",“File|Open”)), this);//创建一个快捷键然后还是进行绑定信号与槽,后面在槽函数内对文件进行操作即可
2.10、QT事件
int main(int argc, char *argv[])
{QApplication a(argc, argv);MainWindow* w = new MainWindow;w.show();return a.exec();
}
事件在Qt中产生之后,的分发过程是这样的:
- 当事件产生之后,Qt使用用应用程序对象调用 notify() 函数将事件发送到指定的窗口:
[override virtual] bool QApplication::notify(QObject *receiver, QEvent *e); - 事件在发送过程中可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤。
// 需要先给窗口安装过滤器, 该事件才会触发 [virtual] bool QObject::eventFilter(QObject *watched, QEvent *event) - 当事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类 :
[override virtual protected] bool QWidget::event(QEvent *event); - 事件分发器会将分类之后的事件(鼠标事件、键盘事件、绘图事件。。。)分发给对应的事件处理 器函数进行处理,每个事件处理器函数都有默认的处理动作(我们也可以重写这些事件处理器函 数),比如:鼠标事件:
// 鼠标按下 [virtual protected] void QWidget::mousePressEvent(QMouseEvent *event); // 鼠标释放 [virtual protected] void QWidget::mouseReleaseEvent(QMouseEvent *event); // 鼠标移动 [virtual protected] void QWidget::mouseMoveEvent(QMouseEvent *event);我们可以去看看支持重写的事件有多少,我们可以去手册查看QWidget类的Protected Functions:(这里没有完全展现出来)
这里我们挑几个出来重写一下test一下:
.h文件class Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public://声明事件处理函数void enterEvent(QEvent *event) override;//进入运行框函数重写void leaveEvent(QEvent *event) override;//离开运行框函数重写void wheelEvent(QWheelEvent *event) override;//进入运行框滚动滑轮函数重写void closeEvent(QCloseEvent *event) override;//关闭运行框函数重写void resizeEvent(QResizeEvent *event) override;//放大缩小运行框函数重写private:Ui::Widget *ui;
};.c文件//进入运行框处理函数
void Widget::enterEvent(QEvent *event)
{qDebug() << "mouse enter";
}
//离开运行框处理函数
void Widget::leaveEvent(QEvent *event)
{qDebug() << "mouse leave";
}
//进入运行框滚轮滑动处理函数
void Widget::wheelEvent(QWheelEvent *event)
{qDebug() << event->angleDelta();}
//关闭运行框处理函数
void Widget::closeEvent(QCloseEvent *event)
{int ret = QMessageBox::warning(this, tr("My Application"),tr("close the window\n""Do you want to close the window?"),QMessageBox::Ok | QMessageBox::No);switch(ret){case QMessageBox::Ok:event->accept();break;case QMessageBox::No:event->ignore();break;}}
//放大缩小运行框处理函数
void Widget::resizeEvent(QResizeEvent *event)
{qDebug() << "oldSize:" << event->oldSize()<< "newSize:" << event->size();
}
运行结果:
2.10.1、利用事件制作自定义按键
我们在文件中新建一个类:
我这里起名为Mybotton继承于Widget(注意第一个字母要大写)
.h文件#ifndef MYBOTTON_H
#define MYBOTTON_H#include <QWidget>class Mybotton : public QWidget
{Q_OBJECT
public:explicit Mybotton(QWidget *parent = nullptr);protected:void leaveEvent(QEvent *event) override;//离开widget窗口void enterEvent(QEvent *event) override;//进入widget窗口signals:};#endif // MYBOTTON_H.c文件#include "mybotton.h"#include <QDebug>Mybotton::Mybotton(QWidget *parent) : QWidget(parent)
{}void Mybotton::leaveEvent(QEvent *event)
{qDebug() << "lll";
}void Mybotton::enterEvent(QEvent *event)
{qDebug() << "kkk";
}
然后因为我们是继承于Widget类,所以我们生成一个Widget:
然后右键点击矩形,点击提升为我们刚才创建的类:
运行结果:
2.10.2、自定义按键信号与槽
这里可以回忆一下前面自定义信号与槽的使用:
mybotton.hclass Mybotton : public QWidget
{Q_OBJECT
public:explicit Mybotton(QWidget *parent = nullptr);protected:void leaveEvent(QEvent *event) override;//离开widget窗口void enterEvent(QEvent *event) override;//进入widget窗口signals:void clicked();//声明信号};widget.cpp:Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);connect(ui->mybtn,&Mybotton::leaved,[=](){qDebug() << "myButton is leaved !";});connect(ui->mybtn,&Mybotton::entered,[=](){qDebug() << "myButton is entered !";});
}mybotton.cpp:void Mybotton::leaveEvent(QEvent *event)
{qDebug() << "lll";emit leaved();//触发信号
}void Mybotton::enterEvent(QEvent *event)
{qDebug() << "kkk";emit entered();
}
运行结果:
2.10.3、事件实现控制字体大小
首先我们要实现Ctrl+鼠标控制字体大小,我们需要重写鼠标滑动事件和键盘输入事件执行动作,两者合起来就可以实现了!
我们新建一个类,基于QTextEdit类

新建一个文本并且提升为MyTextEdit:
代码:
mytextedit.h#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QTextEdit>class MyTextEdit : public QTextEdit
{
public:MyTextEdit(QWidget *parent);//需要添加代码的地方protected:void wheelEvent(QWheelEvent *e) override;void keyPressEvent(QKeyEvent *e) override;void keyReleaseEvent(QKeyEvent *e) override;private:bool ctrlKeyPressed = 0;//Ctrl是否被按下标志位};#endif // MYTEXTEDIT_Hmytextedit.c#include "mytextedit.h"#include <QWheelEvent>
#include <QDebug>MyTextEdit::MyTextEdit(QWidget *parent) : QTextEdit(parent)
{}void MyTextEdit::wheelEvent(QWheelEvent *e)
{qDebug() << "wheelEvent";if(ctrlKeyPressed == 1){if(e->angleDelta().y() > 0){//放大字体qDebug() << "fangda";}else if(e->angleDelta().y() < 0){//缩小字体qDebug() << "suoxiao";}e->accept();//事件处理完成}else{QTextEdit::wheelEvent(e);//没有按下Ctrl默认怎么处理就怎么处理}
}void MyTextEdit::keyPressEvent(QKeyEvent *e)
{qDebug() << "keyPressEvent";if(e->key() == Qt::Key_Control){// qDebug() << "ctrl Pressed";ctrlKeyPressed = 1;}QTextEdit::keyPressEvent(e);
}void MyTextEdit::keyReleaseEvent(QKeyEvent *e)
{qDebug() << "keyReleaseEvent";if(e->key() == Qt::Key_Control){// qDebug() << "ctrl Release";ctrlKeyPressed = 0;}QTextEdit::keyPressEvent(e);
}
运行结果:
相关文章:
Qt入门笔记
目录 一、前言 二、创建Qt项目 2.1、使用向导创建 2.2、最简单的Qt应用程序 2.2.1、main函数 2.2.2、widget.h文件 2.2.3、widget.cpp文件 2.3、Qt按键Botton 2.3.1、创建一个Botton 2.3.2、信号与槽 2.3.3、按键使用信号与槽的方法 2.4、文件Read与Write-QFile类 2…...
C语言每日一练——day_4
引言 针对初学者,每日练习几个题,快速上手C语言。第四天。(连续更新中) 采用在线OJ的形式 什么是在线OJ? 在线判题系统(英语:Online Judge,缩写OJ)是一种在编程竞赛中用…...
下降路径最⼩和(medium)
题目描述: 给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(…...
redux_旧版本
reduxjs/toolkit(RTK)是 Redux 官方团队推出的一个工具集,旨在简化 Redux 的使用和配置。它于 2019 年 10 月 正式发布,此文章记录一下redux的旧版本如何使用,以及引入等等。 文件目录如下: 步骤 安装依…...
⭐算法OJ⭐经典题目分类索引(持续更新)
在编程竞赛和算法学习中,Online Judge(OJ)平台是程序员们磨练技能的重要工具。OJ平台上的题目种类繁多,涵盖了从基础数据结构到复杂算法的各个方面。为了更好地理解和掌握这些题目,对其进行分类是非常有必要的。这篇索…...
python之使用scapy扫描本机局域网主机,输出IP/MAC表
安装scapy库 pip install scapy -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple扫描本机局域网的所有主机,输出IP/MAC对于表 # -*- coding: UTF-8 -*- import netifaces from scapy.all import srp from scapy.layers.l2 import ARP, Ether import ipa…...
Spring Boot中@Valid 与 @Validated 注解的详解
Spring Boot中Valid 与 Validated 注解的详解 引言 在Spring Boot应用中,参数校验是确保数据完整性和一致性的重要手段。Valid和Validated注解是Spring Boot中用于参数校验的两个核心注解。本文将详细介绍这两个注解的用法、区别以及代码样例。 Valid注解 功能介…...
18、TCP连接三次握手的过程,为什么是三次,可以是两次或者更多吗【高频】
三次握手的过程: 第一次握手:客户端 向 服务器 发送一个 SYN(也就是同步序列编号报文),请求建立连接。随后,客户端 进入 SYN_SENT 状态;服务器收到 SYN 之后,由 LISTEN 状态变为 SYN…...
Ceph(2):Ceph简介
1 Ceph简介 Ceph使用C语言开发,遵循LGPL协议开源。Sage Weil(Ceph论文发表者)于2011年创立了以Inktank公司主导Ceph的开发和社区维护。2014年Redhat收购inktank公司,并发布Inktank Ceph企业版(ICE)软件,业务场景聚焦云…...
第二篇:CTF常见题型解析:密码学、逆向工程、漏洞利用、Web安全
# 零基础小白入门CTF解题到成为CTF大佬系列文章 ## 第二篇:CTF常见题型解析:密码学、逆向工程、漏洞利用、Web安全 ### 引言 在CTF比赛中,题目类型多种多样,涵盖了网络安全领域的多个方向。掌握这些题型的解题方法,…...
《Python基础教程》附录B笔记:Python参考手册
《Python基础教程》第1章笔记👉https://blog.csdn.net/holeer/article/details/143052930 附录B Python参考手册 Python标准文档是完整的参考手册。本附录只是一个便利的速查表,当你开始使用Python进行编程后,它可帮助你唤醒记忆。 B.1 表…...
linux学习(十三)(shell编程(文字,变量,循环,条件,调试))
Shell 编程 Shell 编程,也称为 shell 脚本,是 Linux作系统不可或缺的一部分。shell 脚本实质上是系统 shell 执行的程序。虽然它可能不如 C 或 C 等编译语言强大,但 shell 编程对于管理级任务、自动执行重复性任务和系统监控非常有效。 大多…...
大模型微调中warmup(学习率预热)是什么
大模型微调中warmup(学习率预热)是什么 在大模型微调中,添加warmup(学习率预热)是指在训练初期逐步增加学习率,避免直接使用高学习率导致参数震荡。 🔧 为什么需要warmup? 大模型参数敏感:预训练模型的参数已接近最优,初期用大学习率可能剧烈扰动参数(如“急刹车…...
wireshark 如何关闭混杂模式 wireshark操作
Fiddler和Wireshark都是进行抓包的工具:所谓抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全。抓包也经常被用来进行数据截取等。黑客常常会用抓包软件获取你非加密的上网数据,然后通过分析&#…...
ChatGPT4.5详细介绍和API调用详细教程
OpenAI在2月27日发布GPT-4.5的研究预览版——这是迄今为止OpenAI最强大、最出色的聊天模型。GPT-4.5在扩大预训练和微调规模方面迈出了重要的一步。通过扩大无监督学习的规模,GPT-4.5提升了识别内容中的模式、建立内容关联和生成对于内容的见解的能力,但…...
centos linux安装mysql8 重置密码 远程连接
1. 下载并安装 MySQL Yum 仓库 从 MySQL 官方网站下载并安装 Yum 仓库配置文件。 # 下载MySQL 8.0的Yum仓库包 wget https://dev.mysql.com/get/mysql80-community-release-el7-5.noarch.rpm # 安装Yum仓库包 sudo rpm -ivh mysql80-community-release-el7-5.noarch.rpm2. 启…...
AWS 如何导入内部SSL 证书
SSL 证书的很重要的功能就是 HTTP- > HTTPS, 下面就说明一下怎么导入ssl 证书,然后绑定证书到ALB. 以下示例说明如何使用 AWS Management Console 导入证书。 从以下位置打开 ACM 控制台:https://console.aws.amazon.com/acm/home。如果您是首次使用 ACM,请查找 AWS Cer…...
Unity DOTS从入门到精通之 自定义Authoring类
文章目录 前言安装 DOTS 包什么是Authoring1. 实体组件2. Authoring类 前言 DOTS(面向数据的技术堆栈)是一套由 Unity 提供支持的技术,用于提供高性能游戏开发解决方案,特别适合需要处理大量数据的游戏,例如大型开放世…...
一键换肤的Qt-Advanced-Stylesheets
项目简介 能在软件运行时对 CSS 样式表主题(包括 SVG 资源和 SVG 图标)进行实时颜色切换的Qt项目。 项目预览: 项目地址 地址:Qt-Advanced-Stylesheets 本地编译环境 Win11 家庭中文版 Qt5.15.2 (MSVC2019) Qt Creator1…...
golang 静态库 Undefined symbol: __mingw_vfprintf
正常用golang编译一个静态库给 其他语言 调用,编译时报错 Error: Undefined symbol: __mingw_vfprintf 很是奇怪,之前用用golang写静态库成功过,编译也没问题,结果却是截然不同。 试了很多次,发现唯一的差别就是在 …...
宝塔的ssl文件验证域名后,会在域名解析列表中留下记录吗?
在使用宝塔面板进行SSL证书验证域名后,通常不会在域名解析列表中留下记录。验证过程中添加的TXT记录仅用于验证域名的所有权,一旦验证完成,就可以安全地删除这些记录,不会影响SSL证书的正常使用。根据搜索结果,DNS验证…...
Linux 网络:skb 数据管理
文章目录 1. 前言2. skb 数据管理2.1 初始化2.2 数据的插入2.2.1 在头部插入数据2.2.2 在尾部插入数据 2.2 数据的移除 3. 小结 1. 前言 限于作者能力水平,本文可能存在谬误,因此而给读者带来的损失,作者不做任何承诺。 2. skb 数据管理 数…...
wireguard搭配udp2raw部署内网
前言 上一篇写了使用 wireguard 可以非常轻松的进行组网部署,但是如果服务器厂商屏蔽了 udp 端口,那就没法了 针对 udp 被服务器厂商屏蔽的情况,需要使用一款 udp2raw 或 socat 类似的工具,来将 udp 打包成 tcp 进行通信 这里以…...
Qwen/QwQ-32B 基础模型上构建agent实现ppt自动生成
关心Qwen/QwQ-32B 性能测试结果可以参考下 https://zhuanlan.zhihu.com/p/28600079208https://zhuanlan.zhihu.com/p/28600079208 官方宣传上是该模型性能比肩满血版 DeepSeek-R1(671B)! 我们实现一个 使用Qwen/QwQ-32B 自动生成 PowerPoi…...
【Linux】使用问题汇总
#1 ssh连接的时候报Key exchange failed 原因:服务端版本高,抛弃了一些不安全的交换密钥算法,且客户端版本比较旧,不支持安全性较高的密钥交换算法。 解决方案: 如果是内网应用,安全要求不这么高…...
PostgreSQL17(最新版)安装部署
PostgreSQL 17已与2024年9月26日正式发布!!! 一、Postgres概述 官网地址:PostgreSQL: The world’s most advanced open source database Postgres作为最先进的开源数据库( the latest version of the world’s most…...
【AI大模型智能应用】Deepseek生成测试用例
在软件开发过程中,测试用例的设计和编写是确保软件质量的关键。 然而,软件系统的复杂性不断增加,手动编写测试用例的工作量变得异常庞大,且容易出错。 DeepSeek基于人工智能和机器学习,它能够依据软件的需求和设计文…...
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台
【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好! 很久没写软文了,今天给大家带了一个干货,如上图,大疆Pocket 3加ENC编…...
机器人交互系统 部署构建
环境要求 Ubuntu 20.04 或更高版本ROS Noetic 或兼容版本Python 3.8 安装步骤 1. 安装ROS环境(如未安装) sudo apt update sudo apt install ros-noetic-desktop-full source /opt/ros/noetic/setup.bash2. 创建工作空间并克隆代码 mkdir -p ~/code…...
Android Telephony 四大服务和数据网络控制面数据面介绍
在移动通信和Android系统中,涉及的关键概念和服务以及场景案例说明如下: 一、概念 (一)Android Telephony 的四大服务 介绍Telephony Data 与 Android Data 的四大服务在Android系统中,与电话(Telephony)和移动数据(Data)相关的核心服务主要包括以下四类: 1. Tele…...

