初识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.mfbz.cn/a/310369.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

适用于安防 音响 车载等产品中中的音频接口选型分析

在人工智能兴起之后&#xff0c;安防市场就成为了其全球最大的市场&#xff0c;也是成功落地的最主要场景之一。对于安防应用而言&#xff0c;智慧摄像头、智慧交通、智慧城市等概念的不断涌现&#xff0c;对于芯片产业催生出海量需求。今天&#xff0c;我将为大家梳理GLOBALCH…

启用Hyper-V的三种方法,总有一种适合你

想在Windows 10计算机上的虚拟机中安装并运行Linux或更早版本的Windows操作系统吗&#xff1f;你将很高兴知道&#xff0c;你不需要第三方虚拟化软件&#xff08;如VirtualBox&#xff09;来在Windows 10上安装和运行Linux和Windows。 Windows 10中的内置Hyper-V工具允许你创建…

Android Studio 实现飞机大战游戏App

&#x1f345;文章末尾有获取完整项目源码方式&#x1f345; 目录 前言 一、运行演示 二、开发环境 三、完成步骤 步骤 1&#xff1a;创建项目 步骤 2&#xff1a;创建包名 步骤 3&#xff1a;实现启动页 步骤 5&#xff1a;实现用户注册 步骤 6&#xff1a;实现用户登…

逃离支原体又陷入流感 | 揭秘呼吸道感染与肠道菌群的隐秘关联

谷禾健康 成人每年大约会患上两到三次普通感冒&#xff0c;儿童每年可能会患上多达八次。而今年尤为显著&#xff0c;各大医院的儿科还是爆满状态&#xff0c;甚至是一号难求。 肺炎支原体感染还没彻底过去&#xff0c;紧接着流感和其他呼吸道病原体感染又跟来了&#xff0c;医…

ffmpeg写YUV420文件碰到阶梯型横线或者条纹状画面的原因和解决办法

版权声明&#xff1a;本文为CSDN博主「文三~」的原创文章&#xff0c;遵循CC 4.0 BY-SA版权协议&#xff0c;转载请附上原文出处链接及本声明。 原文链接&#xff1a;https://blog.csdn.net/asdasfdgdhh/article/details/112831581 留作备份 阶梯型横线&#xff1a; 条纹状画面…

vue前端开发自学,父子组件之间的数据传递demo

vue前端开发自学,父子组件之间的数据传递demo!下面为大家展示的是&#xff0c;vue开发中常见的&#xff0c;父子级别关系的&#xff0c;数据 传递案例。先给大家看一下&#xff0c;源码&#xff0c;然后讲解一下里面的注意事项。 <template><h3>Parent</h3>…

耐高压达林顿输出光隔离器TLP187(TPL,E(O 功能介绍及其应用

TLP187(TPL,E(O 是一款达林顿晶体管耦合器&#xff0c;它因采用了 SO6封装而实现了外形的小巧化&#xff0c;也可以保证高温运转的可行性 &#xff08;Ta110degG最大值)。TLP187可以取代其前一代产品&#xff0c;即现有的TIP127型号。该产品的的焊盘尺寸与现有的MFSOP时装参考尺…

ajax+axios——统一设置请求头参数——添加请求头入参——基础积累

最近在写后台管理系统&#xff08;我怎么一直都只写管理系统啊啊啊啊啊啊啊&#xff09;&#xff0c;遇到一个需求&#xff0c;就是要在原有系统的基础上&#xff0c;添加一个仓库的切换&#xff0c;并且需要把选中仓库对应的id以请求头参数的形式传递到每一个接口当中。。。 …

启动redis出现Creating Server TCP listening socket 127.0.0.1:6379: bind: No error异常

1.进入redis安装目录&#xff0c;地址栏输入cmd 2.输入命令 redis-server.exe redis.windows.conf redis启动失败 解决&#xff0c;输入命令 #第一步 redis-cli.exe#第二步 shutdown#第三步 exit第四步 redis-server.exe redis.windows.conf 显示以下图标即成功

【论文阅读】Deep Graph Infomax

目录 0、基本信息1、研究动机2、创新点2.1、核心思想&#xff1a;2.2、思想推导&#xff1a; 3、准备3.1、符号3.2、互信息3.3、JS散度3.4、Deep InfoMax方法3.5、判别器&#xff1a;f-GAN估计散度 4、具体实现4.1、局部-全局互信息最大化4.2、理论动机 5、实验设置5.1、直推式…

Linux第25步_在虚拟机中备份“ST官方的TF-A源码”

TF-A是ARM公司提供的&#xff0c;ST公司通过修改它&#xff0c;做了一个自己的TF-A代码。因为在后期开发中&#xff0c;若硬件被改变了&#xff0c;我们需要通过修改"ST官方的TF-A源码"就可以自己的TF-A代码了。为了防止源文件被误改了&#xff0c;我们需要将"S…

Linux安装MongoDB教程

下载MongoDB安装包 1、官网地址; 下载链接 选择版本 下载好了之后上传到服务器开始安装。 解压 解压 mongodb-linux-x86_64-rhel70-4.2.23.tgz 文件&#xff1a; 解压文件必须进入到压缩包所在的目录&#xff1a; cd /usr/local tar -zxvf mongodb-linux-x86_64-rhel70-4…

HDFS读写数据流程、NameNode与DataNode工作机制

文章目录 HDFS 写数据流程HDFS 读数据流程HDFS 节点距离计算HDFS 机架感知HDFS NN和2NN工作机制HDFS FsImage镜像文件HDFS Edits编辑日志HDFS 检查点CheckPoint时间设置HDFS 退役旧数据节点HDFS DataNode多目录配置HDFS DataNode工作机制HDFS 数据完整性HDFS 掉线时限参数设置 …

在线HMAC计算工具

HMAC在线加密 - BTool在线工具软件&#xff0c;为开发者提供方便。HMAC是密钥相关的哈希运算消息认证码&#xff08;Hash-based Message Authentication Code&#xff09;的缩写&#xff0c;由H.Krawezyk&#xff0c;M.Bellare&#xff0c;R.Canetti于1996年提出的一种基于Hash…

NATURE子刊 | IF:9.8,中科院2区水刊,审稿速度快!接收领域广!

【SciencePub学术】本期&#xff0c;小编给大家推荐的是一本影响因子为9.0的中科院2区Nature子刊。其详情如下&#xff1a; 期刊简介 SCIENTIFIC DATA ISSN&#xff1a;2052-4463 E-ISSN&#xff1a;—— IF&#xff08;2022&#xff09;&#xff1a;9.8 自引率&#…

【EI会议征稿通知】第五届机电一体化技术与智能制造国际学术会议(ICMTIM 2024)

第五届机电一体化技术与智能制造国际学术会议&#xff08;ICMTIM 2024&#xff09; 2024 5th International Conference on Mechatronics Technology and Intelligent Manufacturing 第五届机电一体化技术与智能制造国际学术会议&#xff08;ICMTIM 2024&#xff09;将于2024…

单极子天线

当双极子天线的一个臂演变为无限大地平面时就形成了一个单极子天线&#xff0c;依据单极子天线形状的不同可以将单极子划分为不同的种类&#xff0c;例如三角锥形、圆锥形、袖形等&#xff0c;这里只关注普通的垂直接地细直单极子天线。 依据镜像原理&#xff0c;单极子天线模型…

ubuntu 挂载新硬盘

1、检测新硬盘 新增加硬盘&#xff0c;检测硬盘识别情况。 命令检查&#xff1a;sudo fdisk -l 3、格式化磁盘 格式化&#xff1a;sudo mkfs.ext4 /dev/sdb 其中&#xff0c;/dev/sdb是新分区的设备文件名&#xff0c;ext4是要使用的文件系统类型。 4、挂载新分区 sudo mk…

学习华为企业无线网络,有这篇文章就够了(二)

学习华为企业无线网络&#xff0c;有这篇文章就够了&#xff08;一&#xff09;https://xmws-it.blog.csdn.net/article/details/135385614 WLAN的基础配置命令 - 配置AP上线 (1) •命令&#xff1a;optioncode [ sub-optionsub-code ] { asciiascii-string | hex hex-string |…

gseaplot3修改一下clusterProfiler默认绘图函数

直接使用clusterProfiler::gseaplot2绘图会出现下边的结果&#xff0c;导致四周显示不全&#xff0c;线的粗细也没办法调整&#xff0c;因为返回的是一个aplot包中的gglist对象&#xff0c;没太多研究。 p1 <- clusterProfiler::gseaplot2(gsea_result, gsea_result$ID, pv…
最新文章