Qt入门笔记

news2025/3/12 19:03:37

目录

一、前言

二、创建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_NAMESPACE

class 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_OBJECT

public:
    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,成功返回1

open_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_OBJECT
    
    public:
        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_OBJECT
    
    public:
        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 clicked
                    qDebug() << "Save";
               break;
           case QMessageBox::Discard:
               // Don't Save was clicked
                    qDebug() << "Discard";
               break;
           case QMessageBox::Cancel:
               // Cancel was clicked
                    qDebug() << "Cancel";
               break;
           default:
               // should never be reached
               break;
         }
    }

    运行结果:

    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_OBJECT
    
    public:
        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_OBJECT
    
    public:
        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.h
    
    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:
        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_H
    
    
    
    mytextedit.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);
    }
    

     运行结果:

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2313897.html

    如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

    相关文章

    C语言每日一练——day_4

    引言 针对初学者&#xff0c;每日练习几个题&#xff0c;快速上手C语言。第四天。&#xff08;连续更新中&#xff09; 采用在线OJ的形式 什么是在线OJ&#xff1f; 在线判题系统&#xff08;英语&#xff1a;Online Judge&#xff0c;缩写OJ&#xff09;是一种在编程竞赛中用…

    下降路径最⼩和(medium)

    题目描述&#xff1a; 给你一个 n x n 的 方形 整数数组 matrix &#xff0c;请你找出并返回通过 matrix 的下降路径 的 最小和 。 下降路径 可以从第一行中的任何元素开始&#xff0c;并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列&#xff08…

    redux_旧版本

    reduxjs/toolkit&#xff08;RTK&#xff09;是 Redux 官方团队推出的一个工具集&#xff0c;旨在简化 Redux 的使用和配置。它于 2019 年 10 月 正式发布&#xff0c;此文章记录一下redux的旧版本如何使用&#xff0c;以及引入等等。 文件目录如下&#xff1a; 步骤 安装依…

    18、TCP连接三次握手的过程,为什么是三次,可以是两次或者更多吗【高频】

    三次握手的过程&#xff1a; 第一次握手&#xff1a;客户端 向 服务器 发送一个 SYN&#xff08;也就是同步序列编号报文&#xff09;&#xff0c;请求建立连接。随后&#xff0c;客户端 进入 SYN_SENT 状态&#xff1b;服务器收到 SYN 之后&#xff0c;由 LISTEN 状态变为 SYN…

    Ceph(2):Ceph简介

    1 Ceph简介 Ceph使用C语言开发&#xff0c;遵循LGPL协议开源。Sage Weil(Ceph论文发表者)于2011年创立了以Inktank公司主导Ceph的开发和社区维护。2014年Redhat收购inktank公司&#xff0c;并发布Inktank Ceph企业版&#xff08;ICE&#xff09;软件&#xff0c;业务场景聚焦云…

    wireshark 如何关闭混杂模式 wireshark操作

    Fiddler和Wireshark都是进行抓包的工具&#xff1a;所谓抓包就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作&#xff0c;也用来检查网络安全。抓包也经常被用来进行数据截取等。黑客常常会用抓包软件获取你非加密的上网数据&#xff0c;然后通过分析&#…

    ChatGPT4.5详细介绍和API调用详细教程

    OpenAI在2月27日发布GPT-4.5的研究预览版——这是迄今为止OpenAI最强大、最出色的聊天模型。GPT-4.5在扩大预训练和微调规模方面迈出了重要的一步。通过扩大无监督学习的规模&#xff0c;GPT-4.5提升了识别内容中的模式、建立内容关联和生成对于内容的见解的能力&#xff0c;但…

    Unity DOTS从入门到精通之 自定义Authoring类

    文章目录 前言安装 DOTS 包什么是Authoring1. 实体组件2. Authoring类 前言 DOTS&#xff08;面向数据的技术堆栈&#xff09;是一套由 Unity 提供支持的技术&#xff0c;用于提供高性能游戏开发解决方案&#xff0c;特别适合需要处理大量数据的游戏&#xff0c;例如大型开放世…

    一键换肤的Qt-Advanced-Stylesheets

    项目简介 能在软件运行时对 CSS 样式表主题&#xff08;包括 SVG 资源和 SVG 图标&#xff09;进行实时颜色切换的Qt项目。 项目预览&#xff1a; 项目地址 地址&#xff1a;Qt-Advanced-Stylesheets 本地编译环境 Win11 家庭中文版 Qt5.15.2 (MSVC2019) Qt Creator1…

    golang 静态库 Undefined symbol: __mingw_vfprintf

    正常用golang编译一个静态库给 其他语言 调用&#xff0c;编译时报错 Error: Undefined symbol: __mingw_vfprintf 很是奇怪&#xff0c;之前用用golang写静态库成功过&#xff0c;编译也没问题&#xff0c;结果却是截然不同。 试了很多次&#xff0c;发现唯一的差别就是在 …

    Linux 网络:skb 数据管理

    文章目录 1. 前言2. skb 数据管理2.1 初始化2.2 数据的插入2.2.1 在头部插入数据2.2.2 在尾部插入数据 2.2 数据的移除 3. 小结 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. skb 数据管理 数…

    wireguard搭配udp2raw部署内网

    前言 上一篇写了使用 wireguard 可以非常轻松的进行组网部署&#xff0c;但是如果服务器厂商屏蔽了 udp 端口&#xff0c;那就没法了 针对 udp 被服务器厂商屏蔽的情况&#xff0c;需要使用一款 udp2raw 或 socat 类似的工具&#xff0c;来将 udp 打包成 tcp 进行通信 这里以…

    Qwen/QwQ-32B 基础模型上构建agent实现ppt自动生成

    关心Qwen/QwQ-32B 性能测试结果可以参考下 https://zhuanlan.zhihu.com/p/28600079208https://zhuanlan.zhihu.com/p/28600079208 官方宣传上是该模型性能比肩满血版 DeepSeek-R1&#xff08;671B&#xff09;&#xff01; 我们实现一个 使用Qwen/QwQ-32B 自动生成 PowerPoi…

    PostgreSQL17(最新版)安装部署

    PostgreSQL 17已与2024年9月26日正式发布&#xff01;&#xff01;&#xff01; 一、Postgres概述 官网地址&#xff1a;PostgreSQL: The world’s most advanced open source database Postgres作为最先进的开源数据库&#xff08; the latest version of the world’s most…

    【AI大模型智能应用】Deepseek生成测试用例

    在软件开发过程中&#xff0c;测试用例的设计和编写是确保软件质量的关键。 然而&#xff0c;软件系统的复杂性不断增加&#xff0c;手动编写测试用例的工作量变得异常庞大&#xff0c;且容易出错。 DeepSeek基于人工智能和机器学习&#xff0c;它能够依据软件的需求和设计文…

    【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台

    【高级篇】大疆Pocket 3加ENC编码器实现无线RTMP转HDMI进导播台 文章目录 准备工作连接设备RTMP概念ENCSHV2推流地址设置大疆Pocket 3直播设置总结 老铁们好&#xff01; 很久没写软文了&#xff0c;今天给大家带了一个干货&#xff0c;如上图&#xff0c;大疆Pocket 3加ENC编…

    机器人交互系统 部署构建

    环境要求 Ubuntu 20.04 或更高版本ROS Noetic 或兼容版本Python 3.8 安装步骤 1. 安装ROS环境&#xff08;如未安装&#xff09; sudo apt update sudo apt install ros-noetic-desktop-full source /opt/ros/noetic/setup.bash2. 创建工作空间并克隆代码 mkdir -p ~/code…

    创建模式-工厂方法模式(Factory Method Pattern)

    江城子乙卯正月二十日夜记梦 目的动机简单工厂示例代码 目的 定义一个创建对象的接口&#xff0c;该接口的子类具体负责创建具体的对象。工厂方法模式将对象的实例化延迟到子类。简单工厂是直接在创建方法中负责所有的产品的生成&#xff0c;造成该方法臃肿&#xff0c;并且当…

    【eNSP实战】交换机配置端口隔离

    交换机端口隔离可以实现在同一个VLAN内对端口进行逻辑隔离&#xff0c;端口隔离分为L2层隔离和L3层隔离&#xff0c;这里只进行L2层隔离演示。 拓扑图 路由器AR1配置GE 0/0/1配置IP&#xff0c;其余PC主机各自配置IP和网关。 现将PC1到PC4四个主机全部进行L2层隔离&#xff0c…

    人脸识别之数据集中 PI20 和 CFMT 之间关联的模型预测贝叶斯(Python+论文代码实现)

    代码文件&#xff08;联系作者点击这里末尾&#xff09; 代码文件描述如下&#xff1a; subjective_objective.ipynb和&#xff1a;这分别是实际的笔记本和 Web 浏览器友好的只读版本。此笔记本读取数据&#xff0c;执行一些预处理&#xff0c;并包含论文中使用的模型规范。它…