初识QT。

文章目录

  • 前言
  • 一、QWidget
    • 1、了解内容
      • main文件中的基本内容。
      • .pro项目文件的内容。
      • mywidget.h文件内容。
      • 命名规范和快捷键
      • Qt助手
    • 2、button按钮
    • 3、对象树
    • 4、信号和槽
    • 5、自定义信号和槽函数
      • 拓展
    • 6、Lambda表达式
    • 7、练习
  • 二、QMainWindow
    • 1、菜单栏和菜单项
    • 2、工具栏
    • 3、状态栏
    • 4、铆接部件(浮动窗口)
    • 5、Qt中资源文件添加
    • 6、对话框
      • 模态对话框和非模态对话框
      • 标准对话框
      • 消息对话框
      • 其它标准对话框
    • 7、界面布局
    • 8、控件
      • Push Button
      • Tool Button
      • Radio Button
      • Check Box
      • List Widget
      • Tree Widget
      • Table Widget
    • 9、其它常用控件
      • Scroll Area
      • Tool Box
      • Tab Widget
      • Stacked Widget
      • Combo Box
      • Font Combo Box
      • Line Edit | Text Edit | Plain Text Edit
      • Spin Box | Double Spin Box
      • Time Edit | Date Edit | Date/Time Edit
      • Horizontal Scroll Bar | Vertical Scroll Bar
      • Horizontal Slider | Vertical Slider
      • Label
    • 10、自定义控件封装
    • 11、Qt中的事件
    • 12、定时器
      • 定时器使用方式1
      • 定时器使用方式2
    • 13、event事件分发器
    • 14、事件过滤器
    • 15、QPainter绘图
    • 16、QPainter高级设置
    • 17、绘图设备
      • QPixmap绘图设备
      • QImage绘图设备
      • QPicture绘图设备
    • 18、Qt文件操作
      • QFile文件读写操作
      • QFileInfo


前言


一、QWidget

1、了解内容

main文件中的基本内容。

在这里插入图片描述

.pro项目文件的内容。

在这里插入图片描述

mywidget.h文件内容。

在这里插入图片描述

命名规范和快捷键

命名规范

类名:首字母大写,单词和单词之间首字面大写。
函数名,变量名称:首字母小写,单词和单词之间首字母大写。

快捷键

注释:ctrl + /
运行:ctrl + r
编译:ctrl + b
字体缩放:ctrl + 鼠标滑轮
查找:ctrl + f
整行移动:ctrl + shift + 上箭头或下箭头
自动对齐:ctrl + i
同名之间的.h和.cpp文件切换:F4
帮助文档第一种方式:F1
帮助文档第二种方式:左侧按键
帮助文档第三种方式:在安装路径下找
在这里插入图片描述

Qt助手

在这里插入图片描述
在这里插入图片描述
例如我们使用了QUdpSocket类,那么就需要引入QUdpSocket头文件,还需要在.pro项目文件中加入network模块。
在这里插入图片描述
在这里插入图片描述

2、button按钮

在这里插入图片描述
在这里插入图片描述

3、对象树

在Qt中当创建的对象在堆区时,如果指定的父亲是QObject派生下来的类或者是QObject的子类派生下来的类,可以不用管理释放的操作,因为会将对象放到对象树中,这样做在一定程度上简化了内存回收机制。
在这里插入图片描述
下面我们创建一个自定义button类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
将自定义button类继承QPushButton类。这样自定义button就有了QPushButton类的一些功能接口函数。
在这里插入图片描述
在这里插入图片描述
下面我们在自定义button的构造函数和析构函数中打印信息。
在这里插入图片描述
然后我们在myWidget窗口中创建一个自定义button。
在这里插入图片描述
我们看到当运行程序时,调用了自定义button的构造函数,当我们点击X将窗口关闭时,程序调用了自定义button的析构函数,但是我们在程序中并没有使用delete,这就是对象树为我们完成了内存回收。即一个父类对象中添加的子类对象都会进入到这个父类对象的child列表中,当这个父类对象析构之前,会先将自己的child列表中的子类对象都先析构完,然后再调用自己的析构函数,这样就保证了父类对象中的资源都释放了。所以qt中有时候不需要手动释放内存。前提是这个父类需要为QObject的派生类。
在这里插入图片描述
在这里插入图片描述
下面我们验证对象树中先调用子类析构函数,再调用父类析构函数。我们在myWidget类的析构函数中也打印信息。
在这里插入图片描述
我们看到打印的结果为先打印myWidget类的析构函数中的内容,然后打印自定义button类的析构函数中的内容。这是因为在执行myWidget对象的析构函数时,会先将析构函数中的代码执行了,然后此时不进行最后一步释放该对象的内容,而是检查是否还有没有释放的子类对象,如果有的话就调用这个子类对象的析构函数,执行这个子类对象的析构函数时也会先将析构函数内的代码先执行,然后不释放子类对象的内容,再次检查子类对象是否还有没有释放的子类对象。直到当前子类对象没有子类了,然后再释放当前子类的内存,然后继续向上一层层释放父类对象的内存。
在这里插入图片描述

4、信号和槽

信号的发送者和信号的接收者通过connect函数建立关联。
信号槽的优点:松散耦合,信号发送端和信号接收端本身是没有关联的,通过connect连接将两端耦合在一起。

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

我们可以在QPushButton的父类中查看到产生信号的函数。
在这里插入图片描述
在这里插入图片描述
我们可以在myWidget的父类QWidget类中找到它的槽函数,通过槽函数可以对当前窗口myWidget进行对应的操作。
在这里插入图片描述
在这里插入图片描述
下面我们给自定义的按钮添加一个功能,当点击这个按钮时,关闭myWidget窗口。需要注意的是使用MyPushButton::clicked和QPushButton::clicked都一样,因为MyPushButton中继承了QPushButton中的clicked函数,而QPushButton中的clicked函数又是从它的父类中继承的。对于槽函数也类似。
在这里插入图片描述

5、自定义信号和槽函数

下面我们来自定义信号和槽函数。
然后我们创建一个Teacher类和一个Student类。
在这里插入图片描述
然后我们在Teacher类中自定义一个信号,信号只需要声明即可,不需要实现。
在这里插入图片描述
在这里插入图片描述
下面我们在Student类中声明一个槽函数,需要注意的是槽函数需要实现。
在这里插入图片描述
在这里插入图片描述
然后我们在Widget窗口中添加Teacher对象和Student对象。并且让Widget中的classIsOver函数中触发老师的hungry信号。然后我们让Teacher的hungry信号和Student的treat槽函数进行连接,这样当检测到hungry信号时,就会调用treat槽函数。需要注意的是可以使用emit关键字来触发信号。
在这里插入图片描述
在这里插入图片描述
我们看到成功触发了hungry信号,并且成功调用了treat槽函数。
在这里插入图片描述
下面我们在Teacher类中添加一个hungry信号的重载版本,即可以传入一个QString对象的参数。然后在Student类中添加一个treat槽函数的重载版本,重载版本中也可以传入一个QString对象的参数。需要注意的是信号的参数一定要和对应的槽函数的参数一致,因为当触发信号后会将信号的参数传递给槽函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后我们让Widget类的classIsOver成员函数中触发Teacher的带参数的hungry信号。
在这里插入图片描述
可以看出将带参数的信号和带参数的槽函数进行连接时,需要多做一步处理。这样编译器才可以分清楚是将哪个重载版本的信号和对应的槽函数进行连接了。
在这里插入图片描述
在这里插入图片描述
我们在上面的结果中看到 “鱼香肉丝” 被打上了双引号,这是因为它为QString对象,想要将这个QString对象转换为char * 类型的字符串,可以使用下面的方法。
在这里插入图片描述
在这里插入图片描述
下面我们将程序中添加一个按钮控件,当点击按钮时触发老师的hungry信号,然后才会调用对应的treat槽函数。
在这里插入图片描述
我们看到确实实现了功能,即当点击按钮时会产生clicked信号,然后调用该信号连接的classIsOver槽函数。在classIsOver槽函数中又会触发hungry信号,然后调用该信号连接的treat槽函数。在这里插入图片描述
上面的方法中使用的是信号和槽函数连接。下面我们使用信号和信号连接的方式来完成上面的操作。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

利用disconnect可以断开信号与槽函数,或者信号与信号之间的连接。
在这里插入图片描述
在这里插入图片描述

拓展

  • 1、信号是可以连接信号的。
  • 2、一个信号可以连接多个槽函数。
  • 3、多个信号可以连接同一个槽函数。
  • 4、信号和槽函数的参数必须类型一一对应,但是信号和槽函数的参数个数可以不一样,只能是信号的参数个数大于槽函数的参数个数,并且槽函数的参数一定要和信号的参数一一对应。
  • 5、Qt5版本以前的信号和槽函数连接方式和Qt5以后的方式不同。

下面我们来看一下Qt5版本以前的信号和槽函数的连接方式。我们看到Qt4版本的connect的缺点是不会做类型检测,所以当信号和槽函数的参数类型不是一一对应时,编译器也检查不出来。下面的SIGNAL和SLOT都为宏。
在这里插入图片描述

6、Lambda表达式

lambda表达式为c++11的新特性,所以当老的版本的项目想要使用lambda表达式时,需要在项目的配置文件中加上CONFIG += c++11。新版本的Qt一般都会自动加上。
在这里插入图片描述
lambda表达式的使用和c++11中的一致,所以可以看前面学习的c++11中的语法。需要注意的是lambda中的mutable关键字,如果lambda表达式的捕获列表中使用值捕获,那么在lambda的函数体中也不可以修改捕获的变量的值,因为默认这个值捕获的变量为const修饰的,所以想要改变这个拷贝的变量的值,就需要加上mutable关键字。加上mutable关键字只是让拷贝的变量的值可以修改了,而外面的变量本体的值还是没有改变。即如果不加mutable关键字修饰,那么在lambda函数体中拷贝的变量的值都无法修改。
下面我们使用lambda表达式触发hungry信号。
在这里插入图片描述
在这里插入图片描述
下面我们在lambda表达式形式的槽函数中执行关闭窗口的操作。我们看到槽函数中可以执行多个操作。
在这里插入图片描述
在这里插入图片描述
如果connect函数的第三个参数为this,第四个参数为lambda表达式。那么第三个参数可以省略。还有需要注意的是在lambda的捕获列表中建议使用值捕获,因为使用&捕获可能会存在bug的情况,即可能出现锁的问题导致捕获的变量无法改变值。
在这里插入图片描述

7、练习

实现两个按钮,一个按钮为open,一个按钮为close。点击open按钮会弹出来一个新的窗口,点击close按钮会将新窗口关闭。
在这里插入图片描述
在这里插入图片描述

二、QMainWindow

1、菜单栏和菜单项

需要注意的是菜单栏只能创建一个。我们可以看到菜单栏创建后并不需要绑定父对象,因为menuBar()函数底层自动做了绑定父对象MainWindow的处理。
在这里插入图片描述
在这里插入图片描述

2、工具栏

工具栏可以有多个。
在这里插入图片描述
这些方法都可以在Qt助手中进行查看和学习。
在这里插入图片描述
下面我们给工具栏中添加内容。我们将创建的菜单项放到工具栏中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、状态栏

状态栏最多只能有一个。
在这里插入图片描述
在这里插入图片描述

4、铆接部件(浮动窗口)

浮动窗口可以有多个。
在这里插入图片描述
我们看到虽然设置时将浮动窗口默认在最下面,但是浮动窗口在上面了,这是因为浮动窗口是根据中心部件来定位的,当前窗口中没有中心部件,所以此时浮动窗口其实就在最下面。
在这里插入图片描述
下面我们给窗口中添加一个中心部件。需要注意的是中心部件只能有一个。
在这里插入图片描述
此时我们看到浮动窗口就在中心部件的下方了。
在这里插入图片描述
然后我们设置浮动窗口只允许在窗口的上下区域停靠。
在这里插入图片描述

5、Qt中资源文件添加

下面我们给菜单项添加图标,我们需要先将图标文件添加到Qt项目中。
我们需要将包含图标的文件放到当前项目的文件目录下。
在这里插入图片描述
在这里插入图片描述
然后我们再添加一个Qt资源文件。
在这里插入图片描述
然后我们就可以看到目录中多了一个资源文件,但是这个资源文件双击是不能进入编辑状态的,需要点击右键,然后点击Open in Editor选项才能进入编辑状态。
在这里插入图片描述
然后我们添加文件时先添加前缀,因为有时候文件比较多,需要用前缀来归类。我们当前图标比较少,直接将前缀为/即可。
在这里插入图片描述
然后我们点击添加文件,选择当前项目目录下的image文件夹中的图标进行添加。
在这里插入图片描述
然后我们就可以看到图标图片都被添加到项目中了。
在这里插入图片描述
下面我们就可以使用这些图片了。
在这里插入图片描述
在这里插入图片描述

6、对话框

模态对话框和非模态对话框

模态对话框在打开期间不可以对其它窗口进行操作,而非模态对话框在打开期间可以对其它窗口进行操作。
下面我们使用设计来创建一个菜单和菜单项,当点击新建菜单项时,弹出一个模态对话框。模态对话框,会阻塞在lambda的函数体中的exec函数内容,在关闭之前不可以对其它窗口做操作。当对话框较小时,编译器就会出现警告。
在这里插入图片描述
在这里插入图片描述
下面我们再创建一个非模态对话框。我们看到非模态对话框就是不调用exec函数让对话框阻塞,而是调用show函数让对话框显示出来。像下面这样直接创建一个dlg2对象,此时对话框会出现后马上销毁,因为当dlg2对象出了lambda函数体的作用域后就销毁了,所以dlg2对象也会销毁。
在这里插入图片描述
所以我们需要将dlg2使用new在堆上创建。此时非模态对话框可以正常显示了。并且可以操作其它窗口。
在这里插入图片描述
但是上面的这样new在堆上创建dlg2对象会造成内存泄漏,即只要大窗口不关闭,那么每次点击新建菜单项都会在堆区中创建一个dlg2对象,并且将小窗口关闭后dlg2对象也不会销毁,这样就造成了内存泄漏。所以我们需要使用setAttribute函数的Qt::WA_DeleteOnClose选项,这样当关闭小窗口时,会将dlg2在堆区的内存释放,这样就不会造成内存泄漏了。
在这里插入图片描述
很多类都有setAttribute函数函数,而且setAttribute函数的选项也很多,我们可以通过Qt助手来进行查看。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

标准对话框

所谓标准对话框,是Qt内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等。这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这样一个对话框。
Qt的内置对话框大致分为以下几类:

QColorDialog:选择颜色
QFileDialog:选择文件或者目录
QFontDialog:选择字体
QInputDialog:允许用户输入一个值,并将其值返回
QMessageBox:模态对话框,用于显示信息,询问问题等
QPageSetupDialog:为打印机提供纸张相关的选项
QPrintDialog:打印机配置
QPrintPreviewDialog:打印预览
QProgressDialog:显示操作过程

消息对话框

下面我们来看一下消息对话框。消息对话框大致分为下面的几类。
在这里插入图片描述
下面我们创建一个错误对话框。
在这里插入图片描述
下面我们创建一个提问对话框。
在这里插入图片描述
我们看到提问对话框的两个按钮默认为yes和no,我们可以通过question函数的第四个参数来设置这两个按钮。我们还可以通过第五个参数来设置默认关联回车按键,即蓝框的按钮。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们看到这几个函数的返回值都是StandardButton类型。这些函数其实会将用户点击的按钮返回,所以我们就可以通过函数的返回值来判断用户点击了哪一个按钮。
在这里插入图片描述

其它标准对话框

下面我们再来简单使用一下其它的标准对话框。
颜色对话框
getColor函数会创建一个颜色对话框,然后返回一个QColor对象,该对象中记录了用户选择的颜色。
在这里插入图片描述
在这里插入图片描述

文件对话框
在这里插入图片描述
我们看到默认为我们打开的是桌面,并且只显示了pdf文件。只会过滤文件,并不会过滤文件夹。
在这里插入图片描述
我们看到QFileDialog::getOpenFileName函数的返回值是一个QString对象,该对象中记录了用户选择的文件的路径。
在这里插入图片描述
字体对话框
QFontDialog::getFont函数返回一个QFont对象,该对象中记录了用户在字体对话框中选择的字体的一些信息。
在这里插入图片描述
在这里插入图片描述

7、界面布局

在Qt中通常使用设计来进行界面的布局,而底层逻辑使用代码实现。下面我们就来学习怎样使用设计来简单进行界面布局。
首先在创建项目时我们需要将创建界面选项勾选上。
在这里插入图片描述
然后我们双击.ui文件来进入设计模式。
在这里插入图片描述
然后我们就进入了设计窗口,因为我们选择创建的是QMainWindow,所以我们可以看到自动生成了菜单栏和工具栏和状态栏。如果不需要,我们就可以进行移除。
在这里插入图片描述
我们可以直接输入来建立菜单和菜单项,需要注意的是菜单项只能使用英语,因为编译器会自动为这个菜单项进行命名。不过我们可以根据菜单项对象的名称在代码中修改它的Text,也可以直接在这个菜单项的属性中直接修改text属性来改变内容。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们重新创建一个项目,然后使用设计来布局一个登录窗口。登录窗口不需要菜单栏、工具栏等,所以我们选择QWidget类。
在这里插入图片描述
我们添加了组件形成了下面的窗口,但是下面的窗口并没有对齐。
在这里插入图片描述
我们可以使用Widget来包含这些组件,然后让Widget中采用水平布局,以此来将这些组件水平对齐。
在这里插入图片描述
我们也可以打破布局来重新进行布局。
在这里插入图片描述
下面我们让用户和密码等四个组件放在一个Widget中,然后将这个Widget使用栅格布局。这样这四个组件就平均了。
在这里插入图片描述
然后我们看窗口效果,可以看到当放大窗口时,登录组件的内容并不会跟着移动。
在这里插入图片描述
我们可以使用弹簧来让登录退出按钮永远保持在中间位置。如果想让中间弹簧的间距保持不变,可以更改中间弹簧的sizeType属性为Fixed,然后修改弹簧的长宽,弹簧就不会改变了。
在这里插入图片描述
可以通过修改Widget的这个属性来让Widget的高度变为和里面的组件高度相同。
在这里插入图片描述
我们可以通过windowTitle属性来修改窗口的名称。
在这里插入图片描述
我们还可以将窗口的最大值和最小值设置为一个定值并且一样,这样窗口大小就不可以缩放了。
在这里插入图片描述
可以通过这个属性来将文本框中的内容隐藏。
在这里插入图片描述

8、控件

下面我们来学习其它控件。

Push Button

我们可以通过下面的方式来给按钮添加图标。
在这里插入图片描述
还可以设置图标的大小。
在这里插入图片描述

Tool Button

一般PushButton显示文字,ToolButton显示图标。ToolButton按钮默认只显示图标,想要文字和图标都显示,需要进行属性修改。autoRaise属性为透明效果。
在这里插入图片描述

Radio Button

下面我们创建四个单选按钮,我们看到这四个按钮中只能有一个处于选中状态。如果我们想让两个为一组的话,那么我们可以使用Group Box来将这四个单选按钮分为两组。
在这里插入图片描述
在这里插入图片描述
下面我们使用代码设置单选按钮,让男默认选中。然后给表示女的单选按钮连接一个槽函数。
我们需要记住表示男的单选按钮和表示女的单选按钮的名称,当然这个名称自己也可以改。
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

Check Box

下面我们再来看多选按钮。
在这里插入图片描述
多选按钮有个自己的信号,stateChanged信号。选中时参数为2,未选中时参数为0,而1是半选的状态。
在这里插入图片描述
在这里插入图片描述

List Widget

List Widget为一个列表容器,我们可以向里面添加要显示的文字内容。
在这里插入图片描述
下面我们向List Widget中添加一行诗。
在这里插入图片描述
在这里插入图片描述
我们还可以一次添加多行到listWidget中。QStringList对象就等价于一个存放String对象的list容器。不过这个QStringList对象重载了<<流插入符,可以以下面的方式添加数据。这种写法不能将每个Item都设为水平居中,但是可以通过for循环来设置。
在这里插入图片描述
在这里插入图片描述

Tree Widget

在这里插入图片描述
下面我们使用Tree Widget来实现一个英雄介绍的案例。
在这里插入图片描述
在这里插入图片描述

Table Widget

Table Widget控件类似于一个表格。
在这里插入图片描述
下面我们使用Table Widget来完成一个记录个人信息的表格。
在这里插入图片描述
在这里插入图片描述

9、其它常用控件

Scroll Area

Scroll Area 为一个滚动区域。
在这里插入图片描述

Tool Box

Tool Box类似于QQ列表的分类。
在这里插入图片描述
可以通过右键来插入页。
在这里插入图片描述

Tab Widget

Tab Widget类似于网站窗口。
在这里插入图片描述

Stacked Widget

在开发时我们可以通过Stacked Widget右上角的小箭头来切换页。
在这里插入图片描述
但是在实际形成的窗口中,这个小箭头就没有了。
在这里插入图片描述
在实际中需要使用按钮或鼠标等来切换页。下面我们设置三个按钮,用来切换这三个页。
在这里插入图片描述
在这里插入图片描述
然后我们就实现了通过点击按钮来切换页。
在这里插入图片描述
但是此时我们会发现这个首页每一次都会变化,并不是索引号为0的每次都默认显示。所以我们需要设置默认定位,即规定好哪一页放在首页。
在这里插入图片描述

Combo Box

Combo Box为下拉框。
在这里插入图片描述
在这里插入图片描述
下面我们添加一个按钮,当点击按钮时,就选中拖拉机。
在这里插入图片描述
在这里插入图片描述

Font Combo Box

Font Combo Box为字体下拉框。
在这里插入图片描述

Line Edit | Text Edit | Plain Text Edit

Line Edit为单行的输入框。
Text Edit为多行输入框。
Plain Text Edit也为多行输入框,但是Plain Text Edit不可以设置文字的颜色,加粗等样式。
在这里插入图片描述

Spin Box | Double Spin Box

Spin Box为单精度。
Double Spin Box为双精度。
在这里插入图片描述

Time Edit | Date Edit | Date/Time Edit

Time Edit为时间选择框。
Date Edit为日期选择框。
Date/Time Edit为日期和时间选择框。
在这里插入图片描述

Horizontal Scroll Bar | Vertical Scroll Bar

Horizontal Scroll Bar 水平滚动条。
Vertical Scroll Bar 垂直滚动条。
在这里插入图片描述

Horizontal Slider | Vertical Slider

Horizontal Slider 为水平滑条。一般可以和Spin Box组合使用。
Vertical Slider 为垂直滑条。一般可以和Spin Box组合使用。
在这里插入图片描述

Label

Label标签可以显示文字,也可以显示图片。
在这里插入图片描述
下面我们利用Label显示图片。
在这里插入图片描述
在这里插入图片描述
Label还可以显示动图。下面我们使用Label显示动图。
在这里插入图片描述
在这里插入图片描述

10、自定义控件封装

下面我们来实现一个自定义控件。如果这个控件想要使用设计来布局,那么就可以添加一个Qt设计师界面类。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样就又形成了一个控件。
在这里插入图片描述
然后我们在这个控件的界面放入一个Spin Box和一个Horizontal Slider滑条,并且使用Widget包含这两个控件,将这两个控件关联组成一个新的自定义控件。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
然后我们回到主窗口的ui界面,添加一个Widget控件。然后将这个控件提升为SmallWidget控件。此时我们运行后就可以看到自定义控件被添加到了主窗口中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们来将Spin Box和Horizontal Slider进行关联。
在这里插入图片描述
在这里插入图片描述
下面我们再添加两个按钮,实现一些功能。
在这里插入图片描述
然后我们在自定义控件中实现两个接口函数。
在这里插入图片描述
在这里插入图片描述
然后将主窗口的两个按钮和自定义控件中的函数进行连接。
在这里插入图片描述
在这里插入图片描述

11、Qt中的事件

Qt中的事件有很多种。
在这里插入图片描述
在这里插入图片描述
下面我们再来自定义一个控件。如果我们不需要这个控件进入ui布局,那么就直接生成C++Class即可,而不需要生成ui文件。
在这里插入图片描述
在这里插入图片描述
因为下面我们需要将Label控件提升为我们自定义的myLabel控件,所以myLabel控件需要继承QLabel。
在这里插入图片描述
然后我们在窗口中添加一个Label控件,并且将这个控件提升为自定义控件。我们可以通过修改属性来使这个控件有边框。
在这里插入图片描述
在这里插入图片描述
下面我们重写myLabel控件中的一些事件函数。那么当在这个自定义控件中发生这些事件时,就会调用重写的事件函数了。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们看到当鼠标进入和离开myLabel控件时,都调用了我们在myLabel类中重写的对应的事件函数。
在这里插入图片描述
上面我们重写的enterEvent函数和leaveEvent函数是myLabel继承QWidget的函数。而myLabel也继承了父类Label中的很多事件函数,下面我们再来重写这几个函数。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们还可以获取鼠标事件的一些信息,这些信息都记录在事件函数的参数ev中。下面我们获取鼠标的坐标信息。x和y获得鼠标相对于控件的左上角的坐标,globalx和globaly获取鼠标相对于桌面的左上角的坐标。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
下面我们判断是鼠标的左键还是右键按下。因为鼠标移动是一个过程性事件,所以我们需要使用&的形式来判断是左键按下移动还是右键按下移动。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们发现只有在控件中按下鼠标按键后,鼠标移动才会捕获鼠标移动的坐标。如果我们想在控件内直接捕获鼠标的移动,而不需要再按键。我们可以设置控件的鼠标追踪为true,默认都为false。
在这里插入图片描述
在这里插入图片描述

12、定时器

定时器使用方式1

在这里插入图片描述
下面我们重写定时器的事件。然后我们创建一个定时器,然后每隔我们设定的事件到时,都会执行一次定时器事件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当我们想要创建两个定时器,并且让这两个定时器执行不同的代码时。我们此时就需要用到timerid来区分定时器。startTimer函数返回的就是定时器的id。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

定时器使用方式2

除了上面的使用方式,定时器还可以像下面这样使用。
在这里插入图片描述
在这里插入图片描述
下面我们再添加一个按钮,当点击这个暂停按钮时,Label4就停止增加。
在这里插入图片描述
在这里插入图片描述

13、event事件分发器

在这里插入图片描述
下面我们通过event事件分发器来拦截鼠标按下事件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

14、事件过滤器

在这里插入图片描述
步骤1.给控件安装事件过滤器。
在这里插入图片描述
步骤2.重写eventFilter事件。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
通过上面的演示我们知道了事件分发器可以在控件中拦截事件,事件过滤器可以在窗口中拦截某个控件的某个事件。

15、QPainter绘图

我们可以通过重新pointEvent事件函数来在Widget窗口中进行绘图。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在画家画画之前还可以对画笔进行设置。画笔的样式等都可以进行调节。需要注意的是一定要先将画笔样式设置好,然后再给画家使用。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
画家还可以使用画刷进行填充颜色,下面我们来设置一个画刷。画刷也可以设置自己想要的样式。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

16、QPainter高级设置

抗锯齿能力。可以让画出的画更精致,但是效率会变低。可以看到右边的圆更精致一些。
在这里插入图片描述
在这里插入图片描述
还可以让画家进行平移,即原来画家从左上角(0,0)位置开始画画,我们可以使用接口函数将画家的位置平移,即改变画家开始画画的位置。
在这里插入图片描述
我们看到使用代码设置的两个矩形的位置是一样的,但是画家画出来后两个矩形并没有重合,这就是因为我们移动了画家的位置。
在这里插入图片描述
我们看到保存了画家位置后,如果还原画家位置,那么就会让画家回到保存的位置进行作画。所以我们看到了只有两个矩形,因为第三次画家作画时回到了(100,0)位置作画,所以第二个矩形和第三个矩形重叠了。
在这里插入图片描述
在这里插入图片描述

我们还可以利用画家来画图片资源等。
在这里插入图片描述
在这里插入图片描述
下面我们添加一个按钮,当点击按钮时,我们让图片像右移动。并且我们设置了当图片向右移动超过窗口宽度后,就让图片重新返回到最左侧。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

17、绘图设备

Qt的绘图系统实际上是使用QPainter在QPainterDevice上进行绘制,它们之间使用QPaintEngine进行通讯(也就是翻译QPainter的指令)。
绘图设备是指继承QPainterDevice的子类,Qt一共提供了四个这样的类,分别是QPixmap,QBitmap,QImage,QPicture。

  • QPixmap专门为图像在屏幕上的显示做了优化。
  • QBitmap是QPixmap的一个子类,它的色深限定为1,可以使用QPixmap的isQBitmap()函数来确定这个QPixmap是不是应该QBitmap。
  • QImage专门为图像的像素级访问做了优化。
  • QPicture可以记录和重现QPainter的各类命令。

QPixmap绘图设备

下面我们使用QPixmap绘图设备向磁盘中进行画画,我们可以看到生成了一个.png图片。
在这里插入图片描述
在这里插入图片描述

QImage绘图设备

下面我们使用QImage绘图设备向磁盘中进行画画。
在这里插入图片描述
在这里插入图片描述
下面我们利用QImage对图片的像素进行修改。我们看到图片中的像素被更改了。
在这里插入图片描述
在这里插入图片描述

QPicture绘图设备

下面我们在QPicture绘图设备上作画,然后记录绘图指令。
在这里插入图片描述
然后我们在paintEvent事件中重现绘图指令。我们看到通过pic.do文件中记录的绘图指令实现了在窗口中进行画画。
在这里插入图片描述
在这里插入图片描述

18、Qt文件操作

QFile文件读写操作

下面我们通过点击选取文件按钮来选择一个文件,并且将这个文件的内容显示到Text Edit中。
在这里插入图片描述
在这里插入图片描述
我们看到选中的文件中的内容都显示到了TextEdit中。
在这里插入图片描述
下面我们使用按行读取的方式将文件的内容进行读取。我们需要注意的是在每次打开文件后,都要记得将文件进行关闭。
在这里插入图片描述
在这里插入图片描述
下面我们来看Qt中向文件中的写操作。
在这里插入图片描述
我们看到选中的文件的后面追加了我们写入的数据。
在这里插入图片描述

QFileInfo

通过QFileInfo可以进行文件信息获取。
通过调用下面的这些函数就可以获取对应文件的信息。
在这里插入图片描述
在这里插入图片描述
我们看到文件的信息被正确显示了。
在这里插入图片描述
在这里插入图片描述
下面我们打印文件的创建日期,我们看到显示的时间的格式可能并不是我们想要的。此时我们可以自己定义打印时间的格式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这样我们就可以根据自己的需要来打印时间了。
在这里插入图片描述
在这里插入图片描述

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

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

相关文章

UKP3d和AutoPDMS管道出图线宽的设置

杭州的一家用户A截轴测图在群里&#xff0c;不料被杭州另一家细心的用户B捕捉到了&#xff0c;B带着疑惑&#xff0c;不相信的口吻问到&#xff1a;“优易抽出来的轴测图吗&#xff1f;我的单线图线很细&#xff0c;这个是怎么设置的&#xff1f;” 可惜&#xff0c;杭州用户A回…

SpringBoot 启动流程

一、SpringBoot 启动流程主要可以概括为以下几个步骤&#xff1a; 加载启动类 当 SpringBoot 项目启动时&#xff0c;会在当前工作目录下寻找有SpringBootApplication注解标识的类&#xff0c;并把这个类作为应用程序的入口点。如果找不到这样的主类&#xff0c;则会打印错误信…

Macos下修改Python版本

MacOS下修改Python版本 安装 查看本机已安装的Python版本&#xff1a;where python3 ~ where python3 /usr/bin/python3 /usr/local/bin/python3 /Library/Frameworks/Python.framework/Versions/3.12/bin/python3如果没有你想要的版本&#xff0c;去python官网下载安装包。…

科技云报道:“存算一体”是大模型AI芯片的破局关键?

科技云报道原创。 在AI发展历史上&#xff0c;曾有两次“圣杯时刻”。 第一次发生在2012年10月&#xff0c;卷积神经网络&#xff08;CNN&#xff09;算法凭借比人眼识别更低的错误率&#xff0c;打开了计算机视觉的应用盛世。 第二次是2016年3月&#xff0c;DeepMind研发的…

解决Java调用Python代码返回中文乱码问题

解决Java调用Python代码返回中文乱码问题 一、乱码原因分析 在Java调用Python代码执行时遇到乱码&#xff0c;我们的第一反应可能是检查文件编码设置是否一致。但在本例中&#xff0c;无论是Java还是Python&#xff0c;编码格式均已设为“UTF-8”&#xff0c;因此排除了编码不…

SSRF扫描工具汇总记录

目录 漏洞简单描述 常出现的位置 工具介绍 SSRFmap 介绍 输入参数

无公网ip如何随时随地远程查看本地群晖NAS存储的文件资源

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…

Linux单主机模拟测试docker macvlan网络

在单台宿主机上使用Linux Bridge&#xff0c;桥接不同网络命名空间&#xff08;namespace&#xff09;的方式&#xff0c;模拟测试docker macvlan网络&#xff0c;记录如下&#xff1a; 参考 链接: Macvlan network driver链接: Docker 网络模型之 macvlan 详解&#xff0c;图…

HackTheBox - Medium - Linux - UpDown

UpDown UpDown 是一台中等难度的 Linux 机器&#xff0c;暴露了 SSH 和 Apache 服务器。在Apache服务器上&#xff0c;有一个Web应用程序&#xff0c;允许用户检查网页是否已启动。服务器上标识了一个名为“.git”的目录&#xff0c;可以下载以显示目标上运行的“dev”子域的源…

三、C++运算符(2)算数运算符

一、递增递减 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<string> using namespace std; int main() {//1、前置递增int a 10;a; //让变量1cout << "a" << a << endl;//2、后置递增int b 10;b;cout << &q…

在 Centos 7.9 下搭建 Nginx Web 服务器的步骤

Nginx是一款高性能的Web服务器&#xff0c;以下是在Linux环境中安装和配置Nginx的详细步骤。 1. 安装必要的软件包 首先&#xff0c;安装gcc-c、pcre、pcre-devel、zlib、zlib-devel、openssl以及openssl-devel等必要的软件包。 yum install -y gcc-c yum install -y pcre y…

Neo4j备份

这里主要讲Neo4j在windows环境下如何备份&#xff0c;Linux环境同理 Neo4j恢复看这里:Neo4j恢复-CSDN博客 Step1:停服 关闭neo4j.bat console会话窗口即可 Step2: 备份 找到数据目录&#xff0c;并备份、压缩 copy即可 data - 20240108.7z Step3: 启动服务 进入命令行&am…

Hive数据库:嵌入、本地、远程全攻略(下)

先介绍一下本地模式和远程模式&#xff1a; 当使用本地模式时&#xff0c;Hive将其元数据存储在本地数据库&#xff08;例如MySQL&#xff09;中&#xff0c;使其成为一个独立的数据处理系统。在本地模式中&#xff0c;Hive的配置文件&#xff08;hive-site.xml&#xff09;中…

浏览器缓存引发的odoo前端报错

前两天&#xff0c;跑了一个odoo16项目&#xff0c;莫名其妙的前端报错&#xff0c; moment.js 报的错&#xff0c; 这是一个时间库&#xff0c;不是我自己写的代码&#xff0c;我也没做过任何修改&#xff0c;搞不清楚为什么报错。以为是odoo的bug&#xff0c;所以从gitee下载…

DevEco Studio for Mac:zsh: command not found: ohpm

一、检查是否配置有ohpm环境 1、新打开一个终端输入export&#xff0c;查看是否有 ohpm路径&#xff1a; 二、如果没有找到ohpm路径&#xff0c;开始配置环境 。 1、查找本机ohpm路径&#xff0c;并记录ohpm解释器的路径&#xff1a; 2、打开终端工具&#xff0c;执行命令 ech…

[力扣 Hot100]Day3 最长连续序列

题目描述 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 出处 思路 此题可用带排序的哈希表&#xff0c;先构建哈希表&#xff0…

现代操作系统复习笔记【核心考点知识+重点复习题】

文章目录 一、核心考点基础知识第一章 概述1、操作系统的基本概念、基本功能2、分时系统、批处理系统、实时系统的主要特征3、用户接口、系统调用过程4、单到与多道程序技术5、操作系统虚拟机体系结构6、CPU工作模式&#xff1b;7、部分课后习题 第二章 进程与线程1、进程的基本…

谷粒学院项目redirect_uri 参数错误微信二维码登录

谷粒学院项目redirect_uri 参数错误_redirect_uri": "http%3a%2f%2fguli.shop%2fapi%2fuce-CSDN博客 修改本地配置 # &#xfffd;&#xfffd;&#xfffd;&#xfffd;˿&#xfffd; server.port8160 # &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#x…

内存分区模型---C++

目录 内存分区模型1.1 程序运行前1.2 程序运行后1.2.1 new操作符 内存分区模型 C程序在执行时&#xff0c;将内存大方向划分为4个区域 代码区&#xff1a;存放函数体的二进制代码&#xff0c;由操作系统进行管理的&#xff1b;全局区&#xff1a;存放全局变量和静态变量以及常…

内存溢出会导致模块测试正常,植入系统失败

前些天&#xff0c;遇到了一个问题&#xff1a;需要在系统中添加一个小功能&#xff0c;单独测试&#xff0c;然后植入系统。 代码使用了从网上下载的函数&#xff0c;模块单独运行&#xff0c;没有问题&#xff0c;但是放在系统中运行就会出问题。 不得已的情况下&#xff0c…