本来应该继续写键盘输入控件QTextEdit的。但是由于QTextEdit继承自QAbstractSocollArea,不按照继承顺序来学,就有些不讲究规律。所以,暂时放一下,准备解决一个目前需要解决的问题,就是将布局给学了。这里有利于后面学习过程中对控件关系、尺寸等问题理解,也方便写代码。在这之前学一下常用的QLabel,会在布局中作为举例使用。
一、标签控件QLabel
1.QLabel的介绍(官翻)
QLabel继承自QFrame
QLabel用于显示文本或图像。不提供用户交互功能。标签的视觉外观可以通过多种方式进行配置,并且可以使用它为另一个小部件指定焦点助记键。
QLabel可以包含以下任何内容类型:
内容 | 设置 |
Plain text | 传递一个普通文本给setText()。 |
Rich text | 传递一个包含富文本的str给setText()。 |
A pixmap | 将QPixmap传递给setPixmap()。 |
A movie | 传递一个QMovie给setMovie()。 |
A number | 向setNum()传递int或double类型,它将数字转换为纯文本。 |
Nothing | 与空的纯文本相同。这是默认值。通过clear()设置。 |
使用这些函数中的任何一个更改内容时,以前的任何内容都将被清除。
默认情况下,标签显示左对齐、垂直居中的文本和图像,其中要显示的文本中的任何选项卡都将自动展开。但是,QLabel的外观可以通过几种方式进行调整和微调。
QLabel小部件区域内的内容位置可以使用setalalignment()和setIndent()进行调整。文本内容也可以使用setWordWrap()沿单词边界换行。例如,下面的代码设置了一个下沉式面板,在右下角有两行文本(两行与标签的右侧齐平):
label = QLabel(self)
label.setFrameStyle(QFrame.Panel | QFrame.Sunken)
label.setText("first line\n second line")
label.setAlignment(Qt.AlignBottom | Qt.AlignRight)
Label从QFrame继承的属性和函数也可用于指定要用于任何给定标签的小部件框架。
QLabel通常用作交互式小部件的标签。为此,QLabel提供了一种有用的机制来添加助记符(参见QKeySequence),该助记符将键盘焦点设置为其他小部件(称为QLabel的“伙伴”)。例如:
phoneEdit = QLineEdit(self)
phoneLabel = QLabel("Phone:", self)
phoneLabel.setBuddy(phoneEdit)
在本例中,当用户按下Alt+P时,键盘焦点转移到标签的伙伴(QLineEdit)。如果伙伴是一个按钮(继承自QAbstractButton),触发助记符将模拟按钮单击。
2.QLabel的相关方法
API函数 | 参数说明 | 返回值 | 功能作用 |
QLabel(self, parent,f) | parent:QWidget f:PySide6.QtCore.Qt.WindowType | None | 创建一个标签对象 |
QLabel(self,text,parent,f) | text:str parent:QWidget f:PySide6.QtCore.Qt.WindowType | None | 创建一个标签对象 |
alignment(self) | None | Qt.AlignmentFlag | 返回内容的对齐方式组合。默认情况下,标签的内容是左对齐和垂直居中的。 |
buddy(self) | None | QWidget | 返回该标签的伙伴,如果当前没有设置伙伴,则返回nullptr。 |
clear(self) | None | None | 清空标签的内容 |
hasScaledContents(self) | None | bool | 获取是否设置内容缩放以填充空白区域。主要针对 图片,文字无效 |
hasSelectedText(self) | None | bool | 获取是否有选中的文本 |
indent(self) | None | int | 获取缩进值 |
margin(self) | None | int | 获取内容边距值 |
minimumSizeHint(self) | None | QSize | 获取最小建议尺寸 |
movie(self) | None | QMovie | 获取设置的动画对象 |
openExternalLinks(self) | None | bool | 获取是否设置点击打开玩不链接 |
picture(self) | None | QPicture | 获取设置的图片 |
pixmap(self) | None | QPixmap | 获取设置的图片 |
selectedText(self) | None | str | 获取被选中的文本内容 |
selectionStart(self) | None | int | 获取选中内容第一个字符在字符串中的索引 |
setAlignment(self, arg__1) | arg__1: PySide6.QtCore.Qt.AlignmentFlag | None | 设置内容对齐方式 |
setBuddy(self, arg__1) | arg__1: PySide6.QtWidgets.QWidget | None | 设置伙伴对象 |
setIndent(self, arg__1) | arg__1: int | None | 设置缩进值 |
setMargin(self, arg__1) | arg__1: int | None | 设置内容边距值 |
setMovie(self, movie) | movie: PySide6.QtGui.QMovie | None | 设置动画 |
setNum(self, arg__1) | arg__1: float | None | 设置文本内容为浮点数 |
setNum(self, arg__1) | arg__1: int | None | 设置文本内容为整型数 |
setOpenExternalLinks(self, open) | open: bool | None | 设置是否开启文本点击开启外部链接模式 |
setPicture(self, arg__1) | arg__1: Union[PySide6.QtGui.QPicture, int] | None | 添加图片 |
setPixmap(self, arg__1) | arg__1: Union[PySide6.QtGui.QPixmap, PySide6.QtGui.QImage, str] | None | 添加图片 |
setScaledContents(self, arg__1) | arg__1: bool | None | 设置图片内容是否自动填充空白区域 |
setSelection(self, arg__1, arg__2) | arg__1: int, arg__2: int | None | 选中字符串中索引为arg_1与 arg_2的内容 |
setText(self, arg__1) | arg__1: str | None | 添加文本 |
setTextFormat(self, arg__1) | arg__1: PySide6.QtCore.Qt.TextFormat | None | 设置文本格式 |
setTextInteractionFlags(self, flags) | flags: PySide6.QtCore.Qt.TextInteractionFlag | None | 设置交互模式 |
setWordWrap(self, on) | on: bool | None | 设置换行策略 |
sizeHint(self) | None | QSize | 获取建议尺寸 |
text(self) | None | str | 获取文本 |
textFormat(self) | None | Qt.TextFormat | 获取文本格式设置 |
textInteractionFlags(self) | None | Qt.TextInteractionFlag | 获取交互模式 |
wordWrap(self) | None | bool | 获取换行策略 |
1)QLabel文本处理的相关方法
在QLabel的介绍中已经说了QLabel既可以设置普通文本,也可以设置富文本,都是通过setText()实现的。这里要说的是和富文本,主要是超链接的内容。例如setOpenExternalLinks(),它的作用是打开富文本中的超链接。比如我们的text是一个html的标签: <a href = "http://baidu.com">百度</a>,此时标签文字会变蓝色高亮带下划线,且当我们点击文字的时候会打开百度的网页。
对于设置的text,标签将自动解释其为普通文本或富文本。但我们可已setTextFormat()方法通过设置文本格式,用以指定文本的格式。setTextFormat()的参数是一个枚举类,其默认值为:Qt.TextFormat.AutoText,这个枚举类也通常用于QTextEdit. setTextFormat()的设置。
枚举类 | 枚举常量 | 枚举值 | 功能描述 |
Qt.TextFormat | PlainText | 文本字符串被解释为纯文本字符串。 | |
RichText | 文本字符串被解释为富文本字符串。有关富文本的定义,请参阅支持的HTML子集。 | ||
AutoText | 自动解释 | ||
MarkdownText | 文本字符串被解释为Markdown的文本。这个枚举值是在Qt 5.14中添加的。。 |
这里枚举类主要就是普通文本与富文本和Markdown格式文本的区别。比如:text=<a href = "http://baidu.com">百度</a>,如果我们设置为RichText或者AutoText,它将会被识别为富文本,具体显示高亮带下划线的“百度”。而如果设置为PlainText,则被识别为普通文本,显示为“<a href = "http://baidu.com">百度</a>”。Markdown格式文本没有了解的请参看高级中的QDocument章节。
selectedText()返回被选中的文本,如果没有选定文本,则返回空字符串。hasSelectedText()则是判断是否有选中的文本。selectionStart()则是返回标签中第一个选定字符的索引,如果没有选择文本则返回-1。这几个方法通常与复制、剪切等动作配合使用,比如我们点击复制按钮,或者使用快捷键“Ctrl+C”时,对应按钮或者action的槽函数中就必须先检测是否有被选中的文本,如果有那么就获取文本放至剪贴板中,如果没有就不执行操作。通常的用户的选中操作是通过鼠标按下并移动,当然由特殊需要的时候编程人员也可以通过setSelection()来以编程方式选中文本,其参数为字符串中应该被选中的开始字符索引和结束字符索引。如:text = Hello world!,setSelection(2,7)的结果就是选中了“llo wo”这几个字符。
而上述这些操作又依赖于QLabel的交互模式设置,交互模式即限制用户可以进行哪些操作。其通过setTextInteractionFlags()来设置,参数是一个枚举类:
枚举类 | 枚举常量 | 枚举值 | 功能描述 |
Qt.TextInteractionFlag | NoTextInteraction | 不能与文本交互(啥也不能干,只能看) | |
TextSelectableByMouse | 可以用鼠标选择文本,并使用上下文菜单或标准键盘快捷键将文本复制到剪贴板。 | ||
TextSelectableByKeyboard | 可以用键盘上的光标键选择文本。显示一个文本光标。 | ||
LinksAccessibleByMouse | 链接可以用鼠标突出显示和激活 | ||
LinksAccessibleByKeyboard | 链接可以使用tab键聚焦,并使用enter键激活。 | ||
TextEditable | 文本是完全可编辑的。 | ||
TextEditorInteraction | 文本编辑器的默认值。 | ||
TextBrowserInteraction | QTextBrowser的默认值。 |
默认情况下的的设置为LinksAccessibleByMouse,实际的显示则是对于链接文本鼠标变为一个可以点击的小手。当然前提是文本为富文本。另外,上面的枚举常量可以通过“|”运算符组合使用,比如我想文本又能点又能选,参数设置为“Qt.TextInteractionFlag.LinksAccessibleByMouse | Qt.TextInteractionFlag.TextSelectableByMouse”
最后,文本的操作还有个换行设置,通过setWordWarp()进行设置,如果参数为True,那么当文本长度超过Label的宽度时,将换行显示。Flase则不换行,不换行的结果就是只显示一部分文本内容,这也是默认的设置。
2)QLabel图片处理的相关方法
图片的添加使用setPixmap()和setPicture()方法。学习阶段图片的设置还是用老方法,直接引用路径即可。而setMovie()则主要添加“.gif”格式动图。其他只有一个setScaledContents()与图片设置有关,这个方法很有用,能够自动将图片大小与lab进行匹配。比如,我们一个展示页面的lab大小为QSize(300,300),但是我们的图片大小是(600*800),这要我们设置其值为Ture,添加图片后,图片会自动匹配lab大小为(300*300)。同时,当lab大小变化时,图片也会随同lab大小一起变化。对于setMovie()也很有用,可以让我们的界面具有动画效果,其参数QMovie我们将在下一小节介绍,具体动图的使用也将在第4小节说明。
其他关于缩进、对齐、内容边距的设置很简单了,就不再过多介绍。
3.QLabel的信号
信号 | 参数说明 | 返回值 | 功能作用 |
linkActivated(link) | link:str | 这个信号在用户单击链接时发出。锚点指向的URL在link,并将其传递给槽函数 | |
linkHovered(link) | link:str | 当用户将鼠标悬停在链接上时,就会发出这个信号。锚点指向的URL在link,并将其传递给槽函数 |
二、QMovie类
1.QMovie的介绍(官翻)
QMovie继承自QObject,这个类用于显示没有声音的简单动画。
首先,通过向QMovie的构造函数传递一个文件的名称或一个指向包含动画图像格式的QIODevice的指针,创建一个QMovie对象。在开始播放动画之前,可以调用isValid()来检查图像数据是否有效。要开始播放动画,需调用start()。QMovie将进入运行状态,触发started()和stateChanged()这两个信号。要取得动画的当前状态,可以调用state()。
要在应用程序中显示动画,可以将QMovie对象传递给QLabel.setMovie()。例子:
label = QLabel()
movie = QMovie("animations/fire.gif")
label.setMovie(movie)
movie.start()
只要电影中有新帧可用,QMovie就会触发updated()。如果帧的大小发生变化,则触发resized()。可以调用currentImage()或currentPixmap()来获得当前帧的副本。当电影结束时,QMovie发出finished()。如果在播放过程中发生任何错误(即图像文件损坏),QMovie将发出error()。
调用setSpeed()可以控制电影播放的速度,它接受的参数是原始速度的百分比。调用setPaused (true)暂停电影。然后,QMovie将进入暂停状态并触发stateChanged()信号。如果调用setPaused (false), QMovie将重新进入运行状态并再次开始播放电影。要停止电影,调用stop()。
某些动画格式允许你设置背景颜色。你可以调用setBackgroundColor()来设置颜色,也可以调用backgroundColor()来取得当前的背景颜色。
currentFrameNumber()返回当前帧的序列号,动画的第一帧序列号为0。frameCount()返回动画中帧的总数(如果图像格式支持的话)你可以调用loopCount()来获取电影在结束前应该循环的次数。nextFrameDelay()返回当前帧应该显示的毫秒数。
调用setCacheMode()可以让QMovie缓存动画的帧。
调用supportedFormats()获取QMovie支持的格式列表。
2.QMovie的相关方法
API函数 | 参数说明 | 返回值 | 功能作用 |
QMovie(self, device, format, parent) | device: PySide6.QtCore.QIODevice, format: Union[PySide6.QtCore.QByteArray, bytes, bytearray, memoryview] = ..., parent: Optional[PySide6.QtCore.QObject] = ... | None | 创建一个标QMovie对象 |
QMovie(self, fileName, format, parent) | filename:str format: Union[PySide6.QtCore.QByteArray, bytes, bytearray, memoryview] = ..., parent: Optional[PySide6.QtCore.QObject] = ... | None | 创建一个标QMovie对象 |
QMovie(self, parent) | parent: Optional[PySide6.QtCore.QObject] = ... | None | 创建一个标QMovie对象 |
backgroundColor(self) | None | QColor | 返回动画的背景颜色。如果没有指定背景色,则返回无效的QColor。 |
cacheMode(self) | None | QMovie.CacheMode | 获取缓存模式 |
currentFrameNumber(self) | None | int | 获取当前帧序列号,第一帧号为0 |
currentImage(self) | None | QImage | 获取当前帧图片 |
currentPixmap(self) | None | QPixmap | 返回当前帧图片 |
device(self) | None | QIODevice | 返回QMovie读取图像数据的设备。如果当前没有分配设备,则返回None。 |
fileName(self) | None | str | 返回QMovie读取图像数据的文件的名称。如果没有分配文件名,或分配的设备不是文件,则返回空字符串。 |
format(self) | None | QByteArray | 返回QMovie在解码图像数据时使用的格式。如果没有指定格式,则返回一个空的QByteArray()。 |
frameCount(self) | None | int | 获取动画的总帧数。不支持此功能的返回0 |
frameRect(self) | None | QRect | 返回上一个帧的rect。如果还没有更新帧,则返回无效的QRect。 |
isValid(self) | None | bool | 如果电影有效(例如,图像数据可读且支持图像格式),返回true;否则返回false。 |
jumpToFrame(self, frameNumber) | frameNumber: int | bool | 跳转到指定帧数的帧。成功时返回true;否则返回false。 |
jumpToNextFrame(self) | None | bool | 跳转到下一帧 |
lastError(self) | None | QImageReader.ImageReaderError | 返回尝试读取图像数据时最近发生的错误。 |
lastErrorString(self) | None | str | 返回在尝试读取图像数据时发生的最新错误的人类可读的表示形式。 |
loopCount(self) | None | int | 返回电影在结束前循环的次数如果电影只播放一次(没有循环),loopCount返回0。如果电影不停地循环,loopCount返回-1。 请注意,如果图像数据来自顺序设备(例如套接字),则只有当cacheMode设置为CacheAll时,QMovie才能循环该影片。 |
nextFrameDelay(self) | None | int | 返回QMovie在更新动画中的下一帧之前等待的毫秒数。 |
scaledSize(self) | None | QSize | 返回缩放后的帧大小。 |
setBackgroundColor(self, color) | color: Union[PySide6.QtGui.QColor, str, PySide6.QtGui.QRgba64, Any, PySide6.QtCore.Qt.GlobalColor, int] | None | 设置背景颜色 |
setCacheMode(self, mode) | mode: PySide6.QtGui.QMovie.CacheMode | None | 设置缓存模式 |
setDevice(self, device) | device: PySide6.QtCore.QIODevice | None | 设置设置当前设备为device。当电影运行时,QMovie将从该设备读取图像数据。 |
setFileName(self, fileName) | fileName: str | None | 设置读取文件路径 |
setFormat(self, format) | format: Union[PySide6.QtCore.QByteArray, bytes, bytearray, memoryview] | None | 将QMovie在解码图像数据时使用的格式设置为格式化。默认情况下,QMovie将尝试猜测图像数据的格式。 |
setPaused(self, paused) | paused: bool | None | 如果paused为true, QMovie将进入paused状态并触发stateChanged (paused);否则,它将进入运行状态并发出stateChanged(正在运行)。 |
setScaledSize(self, size) | size: PySide6.QtCore.QSize | None | 将缩放后的帧大小设置为size。 |
setSpeed(self, percentSpeed) | percentSpeed: int | None | 设置播放速度 |
speed(self) | None | int | 获取播放速度 |
start(self) | None | None | 开始播放动画 |
state(self) | None | QMovie.MovieState | 获取动画当前状态 |
stop(self) | None | None | 停止播放动画 |
supportedFormats() | None | None | 返回QMovie支持的图像格式列表。 |
这里要说明的是,QMovie仅支持“*.gif”和“*.webp”两种格式的动图。“*.webp”是网页格式的动图,部分浏览器不支持,具体参看百度介绍。对于我们开发桌面APP,“.gif”格式就够了。支持的格式是通过其静态方法supportedFormats()获取的。
对于QIODevice类,我们将在数据读取和文件管理章节介绍。
setCacheMode(),format()等方法主要与网络编程相关,setCacheMode()的参数是一个枚举类:
枚举类 | 枚举常量 | 枚举值 | 功能描述 |
QMovie.CacheMode | CacheNone | 不缓存帧(默认设置) | |
CacheAll | 缓存所有帧 |
这里简单说以下帧的概念,如gif动图,和我们看翻页书动画片一样,一个连续的动画是由一页一页的图片组合起来的,那么这一页页的图片就是帧。
官网对缓存这么说明:当依赖于解码动画数据的底层动画格式处理程序不支持跳转到特定帧或甚至“回放”动画到开始(用于循环)时,缓存帧可能是有用的。此外,如果图像数据来自顺序设备,则底层动画处理程序无法跳转到已读取数据的帧(这使得循环完全不可能)。为了解决此类问题,可以指示对象缓存帧,但这会增加额外的内存开销,即在对象的生命周期内将帧保存在内存中。
说人话就是:当我们用的动图不支持循环播放或跳转播放时(原图不支持这么做),我们就需要将它拆成每一帧存在我们内存中。如此,我们在实现循环和跳帧功能时,Qt就会帮助我们把存的这些帧拿出来完成功能。而对于网络编程,图片如果来自于服务器,我们将它存下来,就可以本地运行,不用断网了就卡住了。对于前述的顺序设备,就是这些数据是的设备仅仅支持一个存储单元一个存储单元的读取信息,不能随机读取,如磁带。那么肯定就不能跳转。
其他的基本功能第一小节介绍中已经说的很清楚,具体使用见后面的例子。
3.QMovie的信号
信号 | 参数说明 | 返回值 | 功能作用 |
error(error) | error:ImageReaderError | 当播放过程中出现错误时,会发出此信号。它将停止播放电影,并进入错误状态。 | |
finished() | link:str | 当动画播放完毕时,会发出这个信号。 | |
frameChanged(frameNumber) | frameNumber:int | 当帧号发生变化时,会发出此信号 | |
resized(size) | Size:QSize | 当前帧被缩放时,会发出此信号 | |
started() | None | 在调用start()之后,会发出这个信号,并且 已经进入了running状态 | |
stateChanged(state) | State:MovieState | 每当电影状态发生变化时,就会发出这个信号 | |
updated(rect) | rect:QRect | 当前帧中的矩形对象被更新时,会发出此信号。 |
example:
from PySide6.QtWidgets import QLabel,QApplication
from PySide6.QtCore import Qt
from PySide6.QtGui import QMovie
import sys
class expmale(QLabel):
def __init__(self):
super(expmale, self).__init__()
self.resize(300, 300)
self.movie = QMovie(self)
self.movie.setFileName("吹风.gif")
self.setMovie(self.movie)
self.setScaledContents(True)
# 跳转到第一帧,不这么设置界面出来会是白板
self.movie.jumpToFrame(0)
# 获取默认速度
self.speed = self.movie.speed()
print(QMovie.supportedFormats())
def keyPressEvent(self, ev):
super(expmale, self).keyPressEvent(ev)
# 空格键控制暂停和播放
if ev.key() == Qt.Key.Key_Space:
if self.movie.state() == QMovie.MovieState.Running:
self.movie.setPaused(True)
else:
self.movie.start()
# S键控制停止
elif ev.key() == Qt.Key.Key_S:
self.movie.stop()
# Tab键控制逐帧播放
elif ev.key() == Qt.Key.Key_Tab and self.movie.state() == QMovie.MovieState.Paused:
self.movie.jumpToNextFrame()
# 上下键控制播放速度
elif ev.key() == Qt.Key.Key_Up:
self.speed += 10
self.movie.setSpeed(self.speed)
elif ev.key() == Qt.Key.Key_Down:
self.speed -= 10
self.movie.setSpeed(self.speed)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = expmale()
win.show()
sys.exit(app.exec())
运行结果:
20241010-141816