PyQt学习Ⅳ(PyQt5小部件)

PyQt5小部件

窗口小部件是应用程序的基本构建块。PyQt5有各种各样的小部件,包括按钮,复选框,滑块或列表框。在本教程的这一部分中,我们将描述几个有用的小部件: QCheckBox,切换模式的QPushButtonQSliderQProgressBar和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

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。

猜你喜欢

转载自blog.csdn.net/qq_41740705/article/details/81270269
今日推荐