赞
踩
窗口小部件是应用程序的基本构建块。PyQt5有各种各样的小部件,包括按钮,复选框,滑块或列表框。在本教程的这一部分中,我们将描述几个有用的小部件: QCheckBox
,切换模式的QPushButton
,QSlider
,QProgressBar
和QCalendarWidget
。
QCheckBox
QCheckBox
是一个具有两种状态的小部件:打开和关闭。这是一个带有标签的盒子。复选框通常用于表示可以启用或禁用的应用程序中的功能。
在我们的示例中,我们将创建一个用于切换窗口标题的复选框。
先来看一下效果吧:
那么就先来说一下这个toggle()的作用,它的作用就是改变初始勾选框的状态,默认的初始状态应该是不勾选的,如果出现奇数次toggle,就会勾上,偶数次就和默认一样,不勾选。
然后我们来关注一下stateChanged这个信号。
如果勾选的话,这个stateChanged会返回一个2,如果没变,返回的是1,不勾选,返回0。那么根据切换按钮状态,这个信号才会发送,1是永远不会被发送的。
cb.stateChanged.connect(self.changeTitle)
def changeTitle(self, state):
if state == Qt.Checked:
self.setWindowTitle('QCheckBox')
else:
self.setWindowTitle(' ')
这次我们来彻底理解一下这段代码,首先要理解connect,它是一个很重要的连接函数,把信号和slot关联起来,并且它会把信号传过来的参数也传给slot。changeTile(self,state)里面的self是从上面一脉相承的self,state就是上面所说的stateChanged发送的那个int,但仅限于0,1,2。Qt.Checked就是2而已,也就是选中,所以显示标题,不是2(其实不是2就是0)呢,就不显示,。那么我们知道了这些完全可以像下面那样写。
切换按钮
切换按钮QPushButton
处于特殊模式。这是一个按钮,有两种状态:按下和未按下。我们通过点击它们在这两种状态之间切换。在某些情况下,此功能非常适合。
在我们的示例中,我们创建了三个切换按钮和一个QWidget
。我们将背景颜色设置 QWidget
为黑色。切换按钮将切换颜色值的红色,绿色和蓝色部分。背景颜色取决于按下的切换按钮。
首先其实这个程序是有问题的。我们来试一下就知道了。
为什么点了绿色,显示的是黄色呢?因为红色加绿色等于黄色,setGreen只是把RGB三色中的绿色部分变了,而R对应得两位十六进制数没有变,那么我们使用setRgb来修改颜色。
我们改成这样。
来看看。
问题又出现了,按一次Red,会显示红色,但是两次红色就会消失,这个原因在pressed参数上面,上面可以看到,按一次pressed参数是true,再一次,就是false了,然后经过
if pressed: val = 255 else: val = 0得判断,就gg了,但是如果我们不想要这样的效果呢。其实很简单。
其实还可以把 if pressed: val = 255 else: val = 0这个判断不要,直接val=255,我为什么敢这么改?就是因为只有按钮按下才能进入slot函数里面。并且从上面的gif,我们认识到redb.clicked[bool].connect(self.setColor)的[bool]可以不要,self.square.setStyleSheet("QFrame { background-color: %s }" % self.col.name())可以改为self.square.setStyleSheet("QWidget { background-color: %s }" % self.col.name()),
并且只有某一个按扭被setCheckable(true),该按钮按下发出的信号连接到slot的pressed这个参数才会有从true到false的跳变,我们上面是直接注释了 redb.setCheckable(True),
其实 redb.setCheckable(False)的效果是一样的。
这里再和以前的程序对比一下
这里我们甚至没有提到setCheckable,因为我们是直接把按下按钮和QApplication.instance().quit连接起来了,不需要传递参数,按照我们上面后来改的其实也不需要pressed这个参数。
QSlider
A QSlider
是具有简单句柄的小部件。这个手柄可以来回拉动。这样我们就可以为特定任务选择一个值。有时使用滑块比输入数字或使用旋转框更自然。
在我们的示例中,我们将显示一个滑块和一个标签。标签将显示图像。滑块将控制标签。
在我们的示例中,我们模拟了音量控制。通过拖动滑块的手柄,我们更改标签上的图像。
sld = QSlider(Qt.Horizontal, self)这句我们以前解释过。
这个Qt.NoFocus和以前设置SizePolicy的时候有点像。关于setFocusPolicy,参考了http://blog.163.com/qimo601@126/blog/static/158220932014563012137/。这个焦点的意思也就是选中部件的方式。
如何看滑块返回的值的最大最小值呢?
最大最小值我们可以设置的。通过下面的两个函数。
或者设置范围。
根据上面的图片,1就相当于Qt.TabFocus,也就是按tab键可以选中滑块,滑块四周出现了边框。
滑块对应的值范围是0-99。
QProgressBar
进度条是我们处理冗长任务时使用的小部件。它是动画的,以便用户知道任务正在进行中。该QProgressBar
小部件在PyQt5工具箱中提供水平或垂直进度条。程序员可以设置进度条的最小值和最大值。默认值为0和99。
在我们的示例中,我们有一个水平进度条和一个按钮。按钮启动和停止进度条。
上面有一点翻译的不够好,start的第一个参数时timeout,这里应该译为间隔时间。
关于QProcessBar可以参考一下https://blog.csdn.net/hebbely/article/details/61418591。
Value()是读取当前的运行值。
把计时器和进度条产生联系的关键代码self.pbar.setValue(self.step)。
QBasicTimer可以看一看https://blog.csdn.net/amnes1a/article/details/62886477。
QBasicTimer 是一个很快的、轻量级的定时器类,它主要被Qt内部使用。所以,我们一般不建议在上层应用程序中直接使用这个类去做定时器工作。在开发应用程序时,我们一般推荐使用QTimer类和QObject的成员函数startTimer来启动定时器。在此,只是出于学习还简单介绍一下QBasicTimer类的使用。还有,该定时器是一种重复性定时器,即它在启动后会不断的向应用程序发送定时器事件,直到你收到调用stop() 时才停止。
也就是计时器会按照start的第一个参数,单位时毫秒为间隔,向接受对象发送一次信息,产生一次timerEvent事件。另外,使用start() 函数启动定时器后,我们随时可以使用stop() 函数来停止它;使用isActive() 函数来判断一个定时器是否正在运行,“正在运行”表示它已经被启动,还未满足停止条件,并且未被stop() 停止。
改变start第一个参数是肯定会变快的。程序一直在打印数字是因为我加了一行。
然后下面我来改两个地方:
我们把终止条件放在1000,但是进度条的数值默认是0到100,后面进度条的数值就一直在100了。我们再来实现一个功能,就是最后点finished会自动退出窗口。加这么一段代码就够了。
QCalendarWidget
QCalendarWidget
提供基于月度的日历小部件。它允许用户以简单直观的方式选择日期。
该示例具有日历窗口小部件和标签窗口小部件。当前选择的日期显示在标签小部件中。
里面的东西以前都是见过的,我们直接运行。setGridVisible也只是显示网格的一个方法。
QPixmap
QPixmap
是用于处理图像的小部件之一。它针对在屏幕上显示图像进行了优化。在我们的代码示例中,我们将使用QPixmap
在窗口上显示图像。
在我们的示例中,我们在窗口上显示图像。
这个例子里面的类,方法我们都见过了,直接看结果。
首先你要准备一张图片了。
QLineEdit
QLineEdit
是一个小部件,允许输入和编辑单行纯文本。可以为窗口小部件提供撤消和重做,剪切和粘贴以及拖放功能。
此示例显示行编辑小部件和标签。我们在行编辑中键入的文本会立即显示在标签小部件中。
当文本内容被改变时,这个信号被发送,参数时新的文本,后面的[signal]代表这个方法是一个信号。
如果注释了adjustSize,标签的大小是固定的,不能随着输入字符数增加变大,因此显示不全所有的字符。
QSplitter
QSplitter
让用户通过拖动子窗口之间的边界来控制子窗口小部件的大小。在我们的示例中,我们组织了两个splitters显示了三个QFrame部件。
在我们的示例中,我们有三个框架小部件和两个分割器。请注意,在某些主题下,拆分器可能看不太清楚。
感觉自己对布局方式没有很好的理解,另外其实我觉得例子也有问题。我们得找几个好的例子来认识布局。布局其实就是窗口小部件的排列方式,有水平的,有竖直的,还有网格的,这我们前面都知道。
简单来设想一下结果,这个结果应该就是三个按钮水平排列,从左到右是1,2,3。
这个结果应该是第一行是3,第二行是1,2并排,并且3和1,2一样长。
实际效果:
上面需要提醒的是我们把布局设定在窗口上有两种方式。一种就是通过上面的setLayout把self和布局关联起来。还有一种是
在创建布局的时候就自动关联。
那么现在可以理解为什么这么会出现下面的结果。因为hbox=QHboxLayout(self)就等于说已经把窗口的布局设定为是水平了,后面再vbox=QVBoxLayout(self)就会出现下面的提示,QLayout尝试去给已经有布局的Example添加布局,但是结果显而易见,是失败的,
所以布局也就是自动给部件排一个位置而已,上面我们全程没有给过任何定位,move,setGeometry这样的方法完全没有用过。如果不设置布局而又不设置位置呢?
为什么只显示一个按钮,因为按钮既没有设置布局,也没有设置定位,默认的定位就是在窗口的左上角,于是就堆在了一起。由此可见,布局是比较省事的,可以避免繁琐的人工定位,在部件多的时候效果更为显著。设定部件的间隔可以用。
那么我们就来分析一下这个QSplitter的例子。
其实hbox = QHBoxLayout(self)和self.setLayout(hbox)的作用重合了,可以去掉一个。
splitter1 = QSplitter(Qt.Horizontal)
splitter1.addWidget(topleft)
splitter1.addWidget(topright)
splitter2 = QSplitter(Qt.Vertical)
splitter2.addWidget(splitter1)
splitter2.addWidget(bottom)
spliiter1是水平排列的,有两个部件,一个是topleft,一个是topright,都是QFrame生成的平板(panel)。然后splitter2是竖直排列的,上面是splitter1,下面是bottom。然后我们先来看一个简单的例子:
看得出来splitter两个部件相邻的边界时可以改变的,当然前提时得有两个部件,一个部件修改不了边界,因为我上面splitter是设定了大小,而splitter里面只有一个部件。我上面没有用布局,如果我把splitter1.setGeometry(10, 10, 100, 100)注释掉,我们找不到边框了,我i猜测可能默认的splitter大小可能是0。而官方给的例子用了水平布局,就不需要我们去担心这个事情。
我删了一些self只是因为我有强迫症,因为那些self都不可以不加,看着就想删。
QComboBox
ComboBox
是一个小部件,允许用户从选项列表中进行选择。
该示例显示了一个QComboBox
和a一个QLabel
。组合框有一个包含五个选项的列表。这些是Linux发行版的名称。标签小部件显示组合框中的选定选项。
关于QCombox,参考了https://www.cnblogs.com/xh-wildgoose/p/5978001.html。
看到activated可以传递两种参数,一种是序号,从0开始的整数,一种是str,默认的应该是int,我是这么想的,那么在例子里 combo.activated[str].connect(self.onActivated)
这个[str]就很关键了,它等于说是选择了返回的参数类型。当然其实我们也不头疼,我们可以不用返回的参数,而是使用currentText。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。