PyQt5教程——组件(7)

组件(widgets)是构建一个应用的基础模块。PyQt5有广泛的各式各样的组件,包含按钮,复选按钮,滑块条,和列表框。在这个部分的教程中,我们将学习几种有用的组件:复选按钮(QCheckBox),切换按钮(ToggleButton),滑块条(QSlider),进度条(ProgressBar)和日历组件(QCalendarWidget)。

 

复选框(QCheckBox)

复选框组件有两种状态:选中和未选中。它是由一个选择框和一个标签组成的。一个应用中,复选框是典型的用来代表有效或无效状态的组件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
"""
ZetCode PyQt5 tutorial
 
In this example, a QCheckBox widget
is used to toggle the title of a window.
 
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
 
import sys
from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication
from PyQt5.QtCore import Qt
 
 
class Example(QWidget):
     
     def __init__( self ):
         super ().__init__()
         
         self .initUI()
         
         
     def initUI( self ):     
 
         cb = QCheckBox( 'Show title' , self )
         cb.move( 20 , 20 )
         cb.toggle()
         cb.stateChanged.connect( self .changeTitle)
         
         self .setGeometry( 300 , 300 , 250 , 150 )
         self .setWindowTitle( 'QCheckBox' )
         self .show()
         
         
     def changeTitle( self , state):
       
         if state = = Qt.Checked:
             self .setWindowTitle( 'QCheckBox' )
         else :
             self .setWindowTitle('')
             
         
if __name__ = = '__main__' :
     
     app = QApplication(sys.argv)
     ex = Example()
     sys.exit(app.exec_())

在我们的例子中,我们创建了一个复选框,用来切换窗口标题。

1
cb = QCheckBox( 'Show title' , self )

这是QCheckBox类的构造方法。

1
cb.toggle()

我们需要设置窗口标题,所以我们必须选中复选框。如果不选中复选框,默认情况下复选框不会被选中所以窗口标题也不会被设置。

1
cb.stateChanged.connect( self .changeTitle)

将我们自定义的changeTitle()槽方法和stateChanged信号连接。changeTitle()方法将用于切换窗口标题。

1
2
3
4
5
6
def changeTitle( self , state):
     
     if state = = Qt.Checked:
         self .setWindowTitle( 'QCheckBox' )
     else :
         self .setWindowTitle('')

复选框组件的状态会传入changeTitle()方法的state参数。如果复选框被选中,我们设置窗口标题。否则,我们把窗口标题设置成一个空字符串。

PyQt5教程——组件(7)_第1张图片Figure: QCheckBox

切换按钮

切换按钮是QPushButton的特殊模式。切换按钮有两种状态:按下和没有按下。我们可以通过点击它在两种状态之间切换。下面的列子展示了切换按钮合适出现的情景。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
"""
ZetCode PyQt5 tutorial
 
In this example, we create three toggle buttons.
They will control the background colour of a
QFrame.
 
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
 
import sys
from PyQt5.QtWidgets import (QWidget, QPushButton,
     QFrame, QApplication)
from PyQt5.QtGui import QColor
 
 
class Example(QWidget):
     
     def __init__( self ):
         super ().__init__()
         
         self .initUI()
         
         
     def initUI( self ):     
 
         self .col = QColor( 0 , 0 , 0 )      
 
         redb = QPushButton( 'Red' , self )
         redb.setCheckable( True )
         redb.move( 10 , 10 )
 
         redb.clicked[ bool ].connect( self .setColor)
 
         redb = QPushButton( 'Green' , self )
         redb.setCheckable( True )
         redb.move( 10 , 60 )
 
         redb.clicked[ bool ].connect( self .setColor)
 
         blueb = QPushButton( 'Blue' , self )
         blueb.setCheckable( True )
         blueb.move( 10 , 110 )
 
         blueb.clicked[ bool ].connect( self .setColor)
 
         self .square = QFrame( self )
         self .square.setGeometry( 150 , 20 , 100 , 100 )
         self .square.setStyleSheet( "QWidget { background-color: %s }" % 
             self .col.name())
         
         self .setGeometry( 300 , 300 , 280 , 170 )
         self .setWindowTitle( 'Toggle button' )
         self .show()
         
         
     def setColor( self , pressed):
         
         source = self .sender()
         
         if pressed:
             val = 255
         else : val = 0
                         
         if source.text() = = "Red" :
             self .col.setRed(val)               
         elif source.text() = = "Green" :
             self .col.setGreen(val)            
         else :
             self .col.setBlue(val)
             
         self .square.setStyleSheet( "QFrame { background-color: %s }" %
             self .col.name()) 
        
        
if __name__ = = '__main__' :
     
     app = QApplication(sys.argv)
     ex = Example()
     sys.exit(app.exec_())

在我们的例子中,我们创建了三个切换按钮和一个QWidget组件。我们把QWidget组件的背景颜色设置为黑色。切换按钮将在红色,绿色和蓝色的RGB值部分进行切换。QWidget组件的背景颜色将取决于哪一个切换按钮被按下。

1
self .col = QColor( 0 , 0 , 0 )

这里是初始化,让RGB值为黑色。

1
2
3
redb = QPushButton( 'Red' , self )
redb.setCheckable( True )
redb.move( 10 , 10 )

要创建切换按钮,就要创建QPushButton,并且调用setCheckable()方法让它可被选中。

1
redb.clicked[ bool ].connect( self .setColor)

我们把clicked信号连接到我们定义的方法上。我们使用clicked信号来操作布尔值。

1
source = self .sender()

我们获得发生状态切换的按钮。

1
2
if source.text() = = "Red" :
     self .col.setRed(val)

在这种情况下,如果发生切换的是red按钮,我们更新RGB值中的红色部分的颜色值。

1
self .square.setStyleSheet( "QWidget { background-color: %s }" %  self .col.name())

我们使用样式表来改变背景颜色。

 

PyQt5教程——组件(7)_第2张图片

Figure: Toggle button

滑块条(QSlider)

滑块条(QSlider)组件有一个简单的可调节手柄。这个手柄可以前后拖动。我们可以使用这个方式来选择具体的数值。有时使用滑块条比直接输入数字或使用数值选择框更自然,在我们下面的例子中,我们将显示一个滑块条和一个标签。标签将会显示一个图像。滑块条将控制标签。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
"""
ZetCode PyQt5 tutorial
 
This example shows a QSlider widget.
 
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
 
import sys
from PyQt5.QtWidgets import (QWidget, QSlider,
     QLabel, QApplication)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
 
 
class Example(QWidget):
     
     def __init__( self ):
         super ().__init__()
         
         self .initUI()
         
         
     def initUI( self ):     
 
         sld = QSlider(Qt.Horizontal, self )
         sld.setFocusPolicy(Qt.NoFocus)
         sld.setGeometry( 30 , 40 , 100 , 30 )
         sld.valueChanged[ int ].connect( self .changeValue)
         
         self .label = QLabel( self )
         self .label.setPixmap(QPixmap( 'mute.png' ))
         self .label.setGeometry( 160 , 40 , 80 , 30 )
         
         self .setGeometry( 300 , 300 , 280 , 170 )
         self .setWindowTitle( 'QSlider' )
         self .show()
         
         
     def changeValue( self , value):
 
         if value = = 0 :
             self .label.setPixmap(QPixmap( 'mute.png' ))
         elif value > 0 and value < = 30 :
             self .label.setPixmap(QPixmap( 'min.png' ))
         elif value > 30 and value < 80 :
             self .label.setPixmap(QPixmap( 'med.png' ))
         else :
             self .label.setPixmap(QPixmap( 'max.png' ))
             
 
if __name__ = = '__main__' :
 
     app = QApplication(sys.argv)
     ex = Example()
     sys.exit(app.exec_())

在我们的例子中,我们模拟了一个音量控制器。通过拖动滑块条的把手,我们可以改变标签的图像。

1
sld = QSlider(Qt.Horizontal, self )

这里我们创建了一个横向的滑块条。

1
2
self .label = QLabel( self )
self .label.setPixmap(QPixmap( 'mute.png' ))

我们创建了一个标签组件,并且设置一个初始的无声图片。

1
sld.valueChanged[ int ].connect( self .changeValue)

我们把valueChanged 信号连接到我们自定义的 changeValue()方法上。

1
2
3
if value = = 0 :
     self .label.setPixmap(QPixmap( 'mute.png' ))
...

这里实现了根据滑块条的值,我们设置不同的标签图片。在上面的代码中,如果滑块条的值等于零,我们为标签设置mute.png图片。

PyQt5教程——组件(7)_第3张图片

Figure: QSlider widget

进度条(QProgressBar)

当我们处理耗时长的任务时,我们需要用到进度条组件。它通过动画的方式让我们了解任务正在处理中。在PyQt5中,进度条组件提供了横向和纵向的进度条选择。程序员可以设置进度条的最大值和最小值。进度条的默认值是0~99。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
"""
ZetCode PyQt5 tutorial
 
This example shows a QProgressBar widget.
 
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
 
import sys
from PyQt5.QtWidgets import (QWidget, QProgressBar,
     QPushButton, QApplication)
from PyQt5.QtCore import QBasicTimer
 
 
class Example(QWidget):
     
     def __init__( self ):
         super ().__init__()
         
         self .initUI()
         
         
     def initUI( self ):     
 
         self .pbar = QProgressBar( self )
         self .pbar.setGeometry( 30 , 40 , 200 , 25 )
 
         self .btn = QPushButton( 'Start' , self )
         self .btn.move( 40 , 80 )
         self .btn.clicked.connect( self .doAction)
 
         self .timer = QBasicTimer()
         self .step = 0
         
         self .setGeometry( 300 , 300 , 280 , 170 )
         self .setWindowTitle( 'QProgressBar' )
         self .show()
         
         
     def timerEvent( self , e):
       
         if self .step > = 100 :
             self .timer.stop()
             self .btn.setText( 'Finished' )
             return
             
         self .step = self .step + 1
         self .pbar.setValue( self .step)
         
 
     def doAction( self ):
       
         if self .timer.isActive():
             self .timer.stop()
             self .btn.setText( 'Start' )
         else :
             self .timer.start( 100 , self )
             self .btn.setText( 'Stop' )
             
         
if __name__ = = '__main__' :
     
     app = QApplication(sys.argv)
     ex = Example()
     sys.exit(app.exec_())

在我们的例子中有一个横向进度条和一个按钮。按钮控制滑块条的开始和停止。

1
self .pbar = QProgressBar( self )

这是滑块条类的构造方法。

1
self .timer = QtCore.QBasicTimer()

我们用定时器对象来激活进度条。

1
self .timer.start( 100 , self )

为了开启定时器事件,我们调用了start()方法。这个方法有两个参数:定时时间和接收定时器事件的对象。

1
2
3
4
5
6
7
8
9
10
def timerEvent( self , e):
   
     if self .step > = 100 :
     
         self .timer.stop()
         self .btn.setText( 'Finished' )
         return
         
     self .step = self .step + 1
     self .pbar.setValue( self .step)

每个QObject类和它的子类都有timerEvent()事件处理函数用于处理定时事件。为了对定时器事件作出反馈,我们重新实现了这个事件处理函数。

1
2
3
4
5
6
7
8
9
def doAction( self ):
   
     if self .timer.isActive():
         self .timer.stop()
         self .btn.setText( 'Start' )
         
     else :
         self .timer.start( 100 , self )
         self .btn.setText( 'Stop' )

在doAction()方法中,我们开始和停止定时器。

PyQt5教程——组件(7)_第4张图片

Figure: QProgressBar

日历组件(QCalendarWidget)

QCalendarWidget类提供了一个基于月的日历组件。它允许用户通过简单的直观的方式选择日期。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/python3
# -*- coding: utf-8 -*-
 
"""
ZetCode PyQt5 tutorial
 
This example shows a QCalendarWidget widget.
 
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
 
import sys
from PyQt5.QtWidgets import (QWidget, QCalendarWidget,
     QLabel, QApplication)
from PyQt5.QtCore import QDate
 
 
class Example(QWidget):
     
     def __init__( self ):
         super ().__init__()
         
         self .initUI()
         
         
     def initUI( self ):     
 
         cal = QCalendarWidget( self )
         cal.setGridVisible( True )
         cal.move( 20 , 20 )
         cal.clicked[QDate].connect( self .showDate)
         
         self .lbl = QLabel( self )
         date = cal.selectedDate()
         self .lbl.setText(date.toString())
         self .lbl.move( 130 , 260 )
         
         self .setGeometry( 300 , 300 , 350 , 300 )
         self .setWindowTitle( 'Calendar' )
         self .show()
         
         
     def showDate( self , date):    
         
         self .lbl.setText(date.toString())
         
         
if __name__ = = '__main__' :
     
     app = QApplication(sys.argv)
     ex = Example()
     sys.exit(app.exec_())

以上的例子展示一个日历组件和标签组件。功能是日历中选择的日期会显示在标签组件中。

1
cal = QCalendarWidget( self )

创建QCalendarWidget类。

1
cal.clicked[QDate].connect( self .showDate)

如果我们在组件上选择了一个日期,clicked[QDate] 信号会被发射。我们把这个信号和自定义的showDate()方法连接。

1
2
3
def showDate( self , date):    
     
     self .lbl.setText(date.toString())

我们通过selectedDate()方法检索被选中的日期。然后我们把选中的日期对象转化成字符串显示在标签组件上。

你可能感兴趣的:(PyQt)