当前位置: 首页 > news >正文

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种:

  1. Designer 中点击:
  2. 使用 QObject::connect(是否使用函数指针)
  3. 使用 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类

QFile Qt 框架中用于文件处理的一个类。它提供了读取和写入文件的功能,支持文本和二进制文 件。
QFile 继承自 QIODevice ,因此它可以像其他 IO 设备一样使用。
主要功能
1. 文件读写 QFile 支持打开文件进行读取或写入操作
2. 文件信息 :可以检索有关文件的信息,如大小、修改日期等。
3. 文件操作 :提供了对文件进行重命名、移动、删除等操作的能力。
4. 错误处理 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读写文件

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

    Qt 框架中, QList 是一个容器类,它在内部实现上类似于一个数组,但也提供了一些链表的特性。
    QList 的设计旨在提供一个在多数情况下既高效又方便的通用列表容器。用于存储元素列表。它提供了 丰富的功能,包括添加、移除、访问元素等。
    QList 的内部工作原理:
    1. 数组式存储 QList 在大多数情况下使用连续内存存储其元素,类似于数组。这意味着它提供了快 速的索引访问(通过下标操作符 [] ),以及相对高效的迭代性能。
    2. 动态调整大小:与静态数组不同, QList 可以动态增长和缩减,自动管理内存分配。
    3. 链表特性:虽然 QList 主要基于数组,但它也提供了一些链表的操作,比如在列表的开始或结束 处添加和移除元素。这些操作通常比在数组中间插入或删除元素更高效。
    4. 复制时共享内存 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(文本字体颜色属性)

    QTextEdit::ExtraSelection 是一个在 QTextEdit 中用来表示额外的文本选择和高亮的结构。

    如何工作: 

    • 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选择条框

    QComboBox Qt 框架中用于创建下拉列表的一个控件。
    它允许用户从一组选项中选择一个选项,并可以配置为可编辑,使用户能够在其中输入文本。
    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

    QMessageBox Qt 框架中用于显示消息框的一个类,它常用于向用户显示信息、询问问题或者报告错 误。以下是 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 

    Qt 中实现快捷键功能通常涉及到 QShortcut 类的使用。下面是一个简单的代码示例,展示了如何在 Qt 应用程序中为特定功能设置快捷键:
    这里使一个使用 Lambda表达式 的一个实例:
    // 创建一个快捷键 (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事件

    事件处理过程:
    众所周知 Qt 是一个基于 C++ 的框架,主要用来开发带窗口的应用程序(不带窗口的也行,但不是主流)。 我们使用的基于窗口的应用程序都是基于事件,其目的主要是用来实现回调(因为只有这样程序的效率 才是最高的)。所以在Qt 框架内部为我们提供了一些列的事件处理机制,当窗口事件产生之后,事件会 经过: 事件派发 -> 事件过滤->事件分发->事件处理 几个阶段。 Qt窗口中对于产生的一系列事件都有默认 的处理动作,如果我们有特殊需求就需要在合适的阶段重写事件的处理动作 比如信号与槽就是一种
    事件( event )是由系统或者 Qt 本身在不同的场景下发出的。当用户按下 / 移动鼠标、敲下键盘,或者是 窗口关闭/ 大小发生变化 / 隐藏或显示都会发出一个相应的事件。一些事件在对用户操作做出响应时发出, 如鼠标/ 键盘事件等;另一些事件则是由系统自动发出,如计时器事件。
    每一个 Qt 应用程序都对应一个唯一的 QApplication 应用程序对象,然后调用这个对象的 exec()
    数,这样 Qt 框架内部的事件检测就开始了( 程序将进入事件循环来监听应用程序的事件 )。
    int main(int argc, char *argv[])
    {QApplication a(argc, argv);MainWindow* w = new MainWindow;w.show();return a.exec();
    }

     事件在Qt中产生之后,的分发过程是这样的:

    1. 当事件产生之后,Qt使用用应用程序对象调用 notify() 函数将事件发送到指定的窗口:
      [override virtual] bool QApplication::notify(QObject *receiver, QEvent *e);
    2. 事件在发送过程中可以通过事件过滤器进行过滤,默认不对任何产生的事件进行过滤。
      // 需要先给窗口安装过滤器, 该事件才会触发
      [virtual] bool QObject::eventFilter(QObject *watched, QEvent *event)
    3. 当事件发送到指定窗口之后,窗口的事件分发器会对收到的事件进行分类 :
      [override virtual protected] bool QWidget::event(QEvent *event);
    4. 事件分发器会将分类之后的事件(鼠标事件、键盘事件、绘图事件。。。)分发给对应的事件处理 器函数进行处理,每个事件处理器函数都有默认的处理动作(我们也可以重写这些事件处理器函 数),比如:鼠标事件:
      // 鼠标按下
      [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…...

    【前端】【nuxt】几种在 Nuxt 客户端使用console的方式

    方法1&#xff1a;在Vue生命周期钩子中使用 只在客户端执行的钩子&#xff08;如mounted&#xff09;中打印&#xff1a; export default {mounted() {console.log(仅在客户端显示, this.$route.path)} }方法2&#xff1a;通过环境判断 使用process.client判断当前环境&…...

    安装 ubuntu 2404 LTS 服务器 设置 服务器名称

    安装 ubuntu服务器 设置 服务器名称 hostname 打开终端&#xff08;Terminal&#xff09;&#xff0c;通过快捷键CtrlAltT或在应用程序中搜索"终端"来打开&#xff1b;在终端中输入以下命令&#xff1a;hostname&#xff0c;然后按下回车键即可查看本机服务器名称。…...

    C语言一维数组

    学习任何数据结构,都可以分为三个主要步骤: 了解基本概念:首先,我们需要理解数据结构的基本概念。以数组为例,首先要知道什么是数组,数组的定义是什么。数组是一种存储固定大小的元素集合的数据结构,它的元素类型是统一的,且通过索引访问。 了解数组的构造和内存分布:…...

    霍夫变换法是基于传统视觉特征的道路车道线检测算法中的一种经典方法

    霍夫变换法是基于传统视觉特征的道路车道线检测算法中的一种经典方法&#xff0c;以下是对它的详细介绍&#xff1a; 基本原理 霍夫变换的基本思想是将图像空间中的点映射到参数空间中&#xff0c;通过在参数空间中寻找峰值来确定图像中特定形状的参数。在车道线检测中&#…...

    静态时序分析:SDC约束命令set_ideal_latency详解

    相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 当使用set_ideal_network命令将当前设计中的一组端口或引脚标记为理想网络源后&#xff0c;理想属性会沿着组合逻辑进行传播&#xff0c;理想网络中的线网和单元…...

    DeepSeek引领端侧AI革命,边缘智能重构AI价值金字塔

    目录 一、AI从“技术炫耀”到“价值兑现” 二、边缘侧部署&#xff1a;从技术挑战到商业必然 三、小规模模型&#xff1a;精度与效率的再平衡 四、Coovally的前瞻性&#xff1a;降低边缘AI开发门槛 五、生产级部署&#xff1a;跨越从实验室到车间的鸿沟 六、未来演进&…...

    完整例子和调用关系qt OpenGL

    项目结构 首先&#xff0c;你需要在 Qt 项目中创建一个类&#xff0c;继承自 QOpenGLWidget 来进行 OpenGL 渲染。文件结构如下&#xff1a; - main.cpp - MyOpenGLWidget.h - MyOpenGLWidget.cpp - vertex_shader.glsl - fragment_shader.glsl 1. main.cpp 这是 Qt 项目的入口…...

    SpringBoot缓存抽象:@Cacheable与缓存管理器配置

    文章目录 引言一、SpringBoot缓存抽象概述二、Cacheable注解详解2.1 Cacheable的关键属性 三、缓存管理器配置四、自定义键生成策略五、缓存同步与失效策略六、SpringBoot缓存最佳实践总结 引言 缓存是提升应用性能的关键技术&#xff0c;SpringBoot提供了强大的缓存抽象层&am…...

    环路广播风暴演示图

    以下是环路广播风暴的演示图及其说明&#xff1a; 环路广播风暴演示图 ----------------- ----------------- | Switch A | | Switch B | | | | | | [Port1]--------------------------[Port1] |…...

    【webrtc debug tools】 rtc_event_log_to_text

    一、rtc_event_log 简介 在学习分析webrtc的过程中&#xff0c;发现其内部提供了一个实时数据捕获接口RtcEventLog。通过该接口可以实时捕获进出webrtc的RTP报文头数据、音视频配置参数、webrtc的探测数据等。其内容实现可参考RtcEventLogImpl类的定义。其文件所在路径 loggin…...

    【统计至简】【古典概率模型】联合概率、边缘概率、条件概率、全概率

    联合概率、边缘概率、条件概率 联合概率边缘概率条件概率全概率 一副标准扑克牌有 54 张&#xff0c;包括 52 张常规牌&#xff08;13 个点数&#xff0c;每个点数有 4 种花色&#xff09;和 2 张王&#xff08;大、小王&#xff09;。我们从中随机抽取一张牌&#xff0c;定义以…...

    Linux 字符设备驱动实例

    编写驱动程序&#xff0c;并将内核模块加载到内核中&#xff0c;等待被用户程序调用。 在控制台中借助第一步申请到的设备号&#xff0c;使用 mknod 命令创建一个设备节点&#xff0c;并拟一个设备名称。 在用户程序中&#xff0c;使用 open 打开第二步中的设备名称&#xff…...

    【git】【网络】【项目配置运行】HTTP 协议的微型简易 Web 服务器---tinyEasyMuduoWebServer

    【git】【网络】【项目配置运行】HTTP 协议的微型简易 Web 服务器—tinyEasyMuduoWebServer csdn项目&#xff1a; 原文链接&#xff1a;https://blog.csdn.net/weixin_45178775/article/details/122257814 github链接&#xff1a;https://github.com/wyewyewye/tinyEasyMuduo…...

    STM32驱动OLED屏幕全解析:从原理到温度显示实战(上) | 零基础入门STM32第五十三步

    主题内容教学目的/扩展视频OLED显示屏重点课程电路原理&#xff0c;手册分析&#xff0c;驱动程序。初始化&#xff0c;清屏&#xff0c;ASCII字库&#xff0c;显示分区。调用显示函数。做带有加入图形和汉字显示的RTC时钟界面。讲字库的设计原理。 师从洋桃电子&#xff0c;杜…...

    2024年9月中国电子学会青少年软件编程(Python)等级考试试卷(三级)答案 + 解析

    更多真题在线练习系统&#xff1a;历年真题在线练习系统 一、单选题 1、以下表达式的值为True的是&#xff1f;&#xff08; &#xff09; A. all( ,1,2,3) B. any([]) C. bool(abc) D. divmod(6,0) 正确答案&#xff1a;C 答案解析&#xff1a;A和B选项&#xff0c;Fal…...

    苍穹外卖实战附源码-DAY1

    一、打开项目的Nginx 1.通过nginx成功打开包装后的前端网页 二、导入sky的数据库 sky.sql 数据 CREATE DATABASE IF NOT EXISTS sky_take_out ; USE sky_take_out;DROP TABLE IF EXISTS address_book; CREATE TABLE address_book (id bigint NOT NULL AUTO_INCREMENT COMMEN…...

    Spring 框架学习

    技术体系结构 总体技术体系 单一架构 一个项目&#xff0c;一个工程&#xff0c;导出为一个 war 包&#xff0c;在一个 Tomcat 上运行&#xff0c;也叫 all in one。 单一架构&#xff0c;项目主要应用技术框架为&#xff1a;Spring、SpringMVC 、Mybatis。 分布式架构 一个…...

    股票交易所官方api接口有哪些?获取和使用需要满足什么条件

    炒股自动化&#xff1a;申请官方API接口&#xff0c;散户也可以 python炒股自动化&#xff08;0&#xff09;&#xff0c;申请券商API接口 python炒股自动化&#xff08;1&#xff09;&#xff0c;量化交易接口区别 Python炒股自动化&#xff08;2&#xff09;&#xff1a;获取…...

    NAT NAPT

    NAT NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09; 主要用于在不同网络&#xff08;如私有网络和公共互联网&#xff09;之间进行 IP 地址转换&#xff0c;解决IP 地址短缺问题&#xff0c;并提供一定的安全性。 IPv4 地址是 32 位&#xf…...

    调优案例一:堆空间扩容提升吞吐量实战记录

    &#x1f4dd; 调优案例一&#xff1a;堆空间扩容提升吞吐量实战记录 &#x1f527; 调优策略&#xff1a;堆空间扩容三部曲 # 原配置&#xff08;30MB堆空间&#xff09; export CATALINA_OPTS"$CATALINA_OPTS -Xms30m -Xmx30m"# 新配置&#xff08;扩容至120MB&am…...

    对比 Vue2 选项式 API 与 Vue3 setup 语法

    对比 Vue2 选项式 API 与 Vue3 setup 语法 1. 代码组织方式 Vue2 选项式 API 通过独立的选项&#xff08;data, methods, computed, watch, 生命周期钩子等&#xff09;组织代码。 export default {data() {return { count: 0 };},methods: {increment() { this.count; }},mou…...

    ragflow-组件可视化工具 es默认用户名elastic

    以下是针对各个后台组件的可视化工具及配置指南&#xff0c;基于您提供的环境变量和端口设置&#xff1a; 1. Elasticsearch 可视化工具: Kibana&#xff08;官方推荐&#xff09;、Cerebro、ElasticHQ访问方式: Kibana&#xff08;集成管理&#xff09;: URL: http://<主机…...

    MATLAB代码开发实战:从入门到高效应用

    一、MATLAB生态系统的核心优势 &#xff08;扩展原有内容&#xff0c;增加行业数据&#xff09; MATLAB在全球工程领域的市场占有率已达67%&#xff08;2024年IEEE统计&#xff09;&#xff0c;其核心优势体现在&#xff1a; 矩阵运算速度比传统编程快3-5倍包含22个专业工具箱…...

    GStreamer —— 2.18、Windows下Qt加载GStreamer库后运行 - “播放教程 6:音频可视化“(附:完整源码)

    运行效果 介绍 GStreamer 带有一组将音频转换为视频的元素。他们 可用于科学可视化或为您的音乐增添趣味 player 的本教程展示了&#xff1a; • 如何启用音频可视化 • 如何选择可视化元素 启用音频可视化实际上非常简单。设置相应的标志&#xff0c;当纯音频流为 found&#…...

    50个经典的python库

    本文整理了50个可以迅速掌握的经典Python库&#xff0c;了解它们的用途&#xff0c;无论你是刚踏上编程之路&#xff0c;还是希望在Python的世界里更加深入&#xff0c;这50个库都能帮助你快速起飞。 1. Taipy Taipy是一个开源Python库&#xff0c;用于轻松的端到端应用程序开…...

    PostgreSQL学习笔记:PostgreSQL vs MySQL

    PostgreSQL 和 MySQL 都是广泛使用的关系型数据库管理系统&#xff0c;它们有以下一些对比&#xff1a; 一、功能特性 1. 数据类型支持 PostgreSQL&#xff1a;支持丰富的数据类型&#xff0c;包括数组、JSON、JSONB、范围类型、几何类型等。对于复杂数据结构的存储和处理非…...

    【CentOS】搭建Radius服务器

    目录 背景简介&#xff1a;Radius是什么&#xff1f;Radius服务器验证原理搭建Radius服务器环境信息yum在线安装配置FreeRADIUS相关文件clients.conf文件users文件重启服务 验证 参考链接 背景 在项目中需要用到Radius服务器作为数据库代理用户的外部验证服务器&#xff0c;做…...

    C#枚举(Enum)详解

    在 C# 中&#xff0c;‌枚举&#xff08;Enum&#xff09;‌ 是一种值类型&#xff0c;用于定义一组命名的常量值&#xff0c;提高代码的可读性和可维护性。以下是枚举的核心概念、用法和最佳实践&#xff1a; ‌1. 枚举的核心特性‌ 类型安全‌&#xff1a;避免使用魔法数字&…...

    DeepSeek进阶应用(一):结合Mermaid绘图(流程图、时序图、类图、状态图、甘特图、饼图)

    &#x1f31f;前言: 在软件开发、项目管理和系统设计等领域&#xff0c;图表是表达复杂信息的有效工具。随着AI助手如DeepSeek的普及&#xff0c;我们现在可以更轻松地创建各种专业图表。 名人说&#xff1a;博观而约取&#xff0c;厚积而薄发。——苏轼《稼说送张琥》 创作者&…...

    Golang | Gin(简洁版)

    文章目录 安装使用RESTful API响应页面获取请求参数路由讲解中间件 安装使用 Gin 是一个 golang 的微框架&#xff0c;封装比较优雅&#xff0c;API 友好&#xff0c;源代码比较明确。具有快速灵活&#xff0c;容错方便等特点。其实对于 golang 而言&#xff0c;web 框架的依赖…...

    【C++ 系列文章 基础 01 -- std::string 与 fmt::format】

    文章目录 Overview1. C 中的 std::string 简介2. fmt::format 格式化函数简介3. 示例代码解析4. 应用场景与优势2. std::string 与 fmt::format 简介std::stringfmt::format 3. 代码解析3.1 格式化字符串生成3.2 调用函数 cmd_handler3.3 返回 id_code 4. 代码整体流程与应用场…...

    有效封装一个 WebSocket 供全局使用

    前言 在现代 Web 应用中&#xff0c;实时通信已经成为越来越重要的一部分。而 WebSocket 技术的出现&#xff0c;使得实时通信变得更加高效和便捷。 WebSocket 协议是一种基于 TCP 协议的双向通信协议&#xff0c;它能够在客户端和服务器之间建立起持久性的连接&#xff0c;从…...

    使用expect工具实现远程批量修改服务器密码

    使用expect工具实现远程批量修改服务器密码 linux服务器安装Expect工具 1、首先查看系统中是否有安装expect。 # whereis expect 2、Expect工具是依赖tcl的&#xff0c;需要先安装tcl #wget https://sourceforge.net/projects/tcl/files/Tcl/8.4.19/tcl8.4.19-src.tar.gz …...

    算法日记39:洛谷P4170涂色(区间DP)

    一、题目 二、题解&#xff1a; 1、题目解析&#xff1a; 1&#xff09;刚刚开始阅读到题目&#xff0c;我们发现并没有什么思路&#xff0c;因此我们可以尝试来模拟一下样例的情况 2&#xff09;通过观察我们发现 n 2 : n2: n2:可以拆分成 1 1 11 11来解决问题 n 3 : n3:…...

    Python学习第十三天

    正则表达式 什么是正则表达式&#xff1a;简单来说就是通过特殊符号匹配想要的字符串&#xff0c;正则表达式本身就是基于字符串的一套搜索规则&#xff0c;掌握了正则表达式对于字符串有了更深的把握和理解。 概念 官网概念&#xff1a;正则表达式&#xff08;Regular Expres…...

    python-53-分别使用flask和streamlit进行向量存储和检索的服务开发实战

    文章目录 1 flask应用1.1 flask服务程序1.2 调用方式2 streamlit应用2.1 streamlit应用程序2.2 操作应用3 参考附录分别基于flask和streamlit,开发了向量存储和检索的应用程序,给出了主体框架的示例,可以在此基础上结合实际应用进行改写。 1 flask应用 1.1 flask服务程序 …...

    Unity热更新方案HybridCLR+YooAsset,从零开始,保姆级教程,纯c#开发热更

    文章目录&#xff1a; 一、前言二、创建空工程三、接入HybridCLR四、接入YooAsset五、搭建本地资源服务器Nginx六、实战七、最后八、后记 一、前言 unity热更有很多方案&#xff0c;各种lua热更&#xff0c;ILRuntime等&#xff0c;这里介绍的是YooAssetHybridCLR的热更方案&a…...

    蓝桥杯嵌入式组第十二届省赛题目解析+STM32G431RBT6实现源码

    文章目录 1.题目解析1.1 分而治之&#xff0c;藕断丝连1.2 模块化思维导图1.3 模块解析1.3.1 KEY模块1.3.2 LED模块1.3.3 LCD模块1.3.4 TIM模块1.3.5 UART模块1.3.5.1 uart数据解析 2.源码3.第十二届题目 前言&#xff1a;STM32G431RBT6实现嵌入式组第十二届题目解析源码&#…...

    Pac-Man(吃豆人) 游戏

    目录 前言 1. Pygame游戏开发基础 1.1 Pygame简介 1.2 游戏开发基本概念 1.3 Pygame核心模块介绍 2. 游戏设计与规划 2.1 游戏规则设计 2.2 游戏对象规划 2.3 技术方案选择 3. 创建游戏窗口与初始化 3.1 初始化Pygame环境 3.2 设置游戏窗口 3.3 定义颜色和游戏参数…...

    Unity Dots从入门到精通 Mono和Dots通讯

    文章目录 前言安装 DOTS 包Mono To DotsDots To Mono 前言 DOTS&#xff08;面向数据的技术堆栈&#xff09;是一套由 Unity 提供支持的技术&#xff0c;用于提供高性能游戏开发解决方案&#xff0c;特别适合需要处理大量数据的游戏&#xff0c;例如大型开放世界游戏。 本文讲…...

    WLAN(无线局域网)安全

    WLAN安全涉及到保护无线局域网免受各种威胁和攻击&#xff0c;以确保数据的保密性、完整性和可用性。以下是关于WLAN安全的多方面介绍&#xff1a; 一、主要安全威胁 窃听&#xff1a;攻击者利用特殊设备监听无线信号&#xff0c;获取传输中的数据&#xff0c;如用户的账号密…...

    故障诊断——neo4j入门

    文章目录 neo4jQuickStartDemo neo4j QuickStart 详情可见博客&#xff1a;https://www.cnblogs.com/nhdlb/p/18703804&#xff0c;使用docker拉取最近的一个版本进行创建 docker run -it -d -p 7474:7474 -p 7687:7687 \ -v /disk5/neo4j_docker/data:/data \ -v /disk5/ne…...

    【商城实战(25)】解锁UniApp移动端适配秘籍,打造完美商城体验

    【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…...

    Qt 数据库操作(Sqlite)

    数据库简介 关于数据库的基础知识这里就不做介绍了&#xff0c;相关博客可以查看&#xff1a; SQL基础知识 数据库学霸笔记 上面博客都写的比较详细&#xff0c;本文主要介绍如何使用Qt进行数据库相关操作&#xff0c;数据库分为关系型数据库和非关系型数据&#xff0c;关系…...

    LINUX 指令大全

    Linux服务器上有许多常用的命令&#xff0c;可以帮助你管理文件、目录、进程、网络和系统配置等。以下是一些常用的Linux命令&#xff1a; 文件和目录管理 ls&#xff1a;列出当前目录中的文件和子目录 bash lspwd&#xff1a;显示当前工作目录的路径 bash pwdcd&#xff1a;切…...

    【Synchronized】不同的使用场景和案例

    【Synchronized】不同的使用场景和案例 【一】锁的作用范围与锁对象【1】实例方法&#xff08;对象锁&#xff09;【2】静态方法&#xff08;类锁&#xff09;【3】代码块&#xff08;显式指定锁对象&#xff09;【4】类锁&#xff08;通过Class对象显式锁定&#xff09; 【二】…...

    华为欧拉操作系统安装Docker服务

    华为欧拉 20.03 操作系统安装 Docker 服务 一、安装前准备 系统环境检查 确认当前运行的操作系统为华为欧拉 24.03。可通过在终端执行以下命令查看&#xff1a; cat /etc/os - release欧拉系统可以使用以下命令&#xff1a; cat /etc/openEuler-release确保系统已连接互联…...

    告别复杂日志解析 用bin2sql轻松实现MySQL数据闪回

    mysqlbinlog⼯具使用 use test; CREATE TABLE t1 (id INT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(20) DEFAULT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;INSERT INTO t1(id, name) SELECT 101, tome101; INSERT INTO t1(id, name) SELECT 102, tome1…...

    uniapp简单table表

    <template><view class"container"><scroll-view scroll-x"true" scroll-y"true" class"table-scroll"><view class"table-header"><view class"table-cell fixed-column">序号<…...