PyQt4 Widgets
::-- zhuyj [2008-06-27 14:31:01]
1. PyQt4 Widgets
PyQt4组件
Widgets are basic building blocks of an application. The PyQt4 programming toolkit has a wide range of various widgets. Buttons, check boxes, sliders, list boxes etc. Everything a programmer needs for his job. In this section of the tutorial, we will describe several useful widgets.
组件是一个应用程序最基本的构成,PyQt4编程工具包包含有大量的各种组件,按钮,检查框,滑块,列表框等等每个程序员都需要的东西。教程的这一节我们将介绍一些有用的组件。
1.1. QCheckBox
QCheckBox is a widget that has two states. On and Off. It is a box with a label. Whenever a checkbox is checked or cleared it emits the signal stateChanged().
- QCheckBox是一个具有两种状态的组件,开或关。它是一个带有标签的方框,一旦一个checkbox被选中或清除都将产生stateChanged()信号。
1 #!/usr/bin/python
2
3 # checkbox.py
4
5 import sys
6 from PyQt4 import QtGui
7 from PyQt4 import QtCore
8
9
10 class CheckBox(QtGui.QWidget):
11 def __init__(self, parent=None):
12 QtGui.QWidget.__init__(self, parent)
13
14 self.setGeometry(300, 300, 250, 150)
15 self.setWindowTitle('Checkbox')
16
17 self.cb = QtGui.QCheckBox('Show title', self)
18 self.cb.setFocusPolicy(QtCore.Qt.NoFocus)
19 self.cb.move(10, 10)
20 self.cb.toggle();
21 self.connect(self.cb, QtCore.SIGNAL('stateChanged(int)'), self.changeTitle)
22
23 def changeTitle(self, value):
24 if self.cb.isChecked():
25 self.setWindowTitle('Checkbox')
26 else:
27 self.setWindowTitle('')
28
29 app = QtGui.QApplication(sys.argv)
30 icon = CheckBox()
31 icon.show()
32 app.exec_()
In our example, we will create a checkbox that will toggle the window title.
- 在这个例子里,我们将创建一个用于控制窗口标题显示的单选框。
self.cb = QtGui.QCheckBox('Show title', self)
This is the QCheckBox constructor.
- 这是一个QCheckBox构造器。
self.cb.setFocusPolicy(QtCore.Qt.NoFocus)
We connect the user defined changeTitle() method to the stateChanged() signal. The changeTitle() method will toggle the window title.
- 我们将我们定义的changeTitle()方法连接到stateChanged()信号。changeTitle()方法用来控制窗口标题。
self.connect(self.cb, QtCore.SIGNAL('stateChanged(int)'), self.changeTitle)
By default, the QCheckBox accepts focus. It is represented by a thin rectangle over the checkbox label. The rectangle looks awful, so I disable it by setting the widget focus policy to Qt.NoFocus.
缺省的,QCheckBox会收到焦点,焦点的样子是checkbox标签外的一个细的矩形。这个矩形看起来太严肃了,所以我通过设置组件的焦点规则为Qt.NoFocus让他不显示了。
self.cb.toggle();
We set the window title, so we must also check the checkbox. By default, the window title is not set and the check box is unchecked.
- 我们设置了窗口的标题,所以我们也必须选择单选框。缺省的窗口标题是没有被设置的并且单选框也没有被选中。toggle(切换)
QCheckBox
Figure: QCheckBox
1.2. ToggleButton
PyQt4 has no widget for a ToggleButton. To create a ToggleButton, we use a QPushButton in a special mode. ToggleButton is a button that has two states. Pressed and not pressed. You toggle between these two states by clicking on it. There are situations where this functionality fits well.
PyQt4没有切换按钮。为了创建一个切换按钮,我们使用QPushButton的特殊模式。切换按钮是一个具有两种状态的按钮,按下和没有按下。通过点击来切换两种不同的状态。有些情况这个功能很适合。
1 #!/usr/bin/python
2
3 # togglebutton.py
4
5 import sys
6 from PyQt4 import QtGui
7 from PyQt4 import QtCore
8
9
10 class ToggleButton(QtGui.QWidget):
11 def __init__(self, parent=None):
12 QtGui.QWidget.__init__(self, parent)
13
14 self.color = QtGui.QColor(0, 0, 0)
15
16 self.setGeometry(300, 300, 280, 170)
17 self.setWindowTitle('ToggleButton')
18
19 self.red = QtGui.QPushButton('Red', self)
20 self.red.setCheckable(True)
21 self.red.move(10, 10)
22
23 self.connect(self.red, QtCore.SIGNAL('clicked()'), self.setRed)
24
25 self.green = QtGui.QPushButton('Green', self)
26 self.green.setCheckable(True)
27 self.green.move(10, 60)
28
29 self.connect(self.green, QtCore.SIGNAL('clicked()'), self.setGreen)
30
31 self.blue = QtGui.QPushButton('Blue', self)
32 self.blue.setCheckable(True)
33 self.blue.move(10, 110)
34
35 self.connect(self.blue, QtCore.SIGNAL('clicked()'), self.setBlue)
36
37 self.square = QtGui.QWidget(self)
38 self.square.setGeometry(150, 20, 100, 100)
39 self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
40
41 QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('cleanlooks'))
42
43 def setRed(self):
44 if self.red.isChecked():
45 self.color.setRed(255)
46 else: self.color.setRed(0)
47
48 self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
49
50 def setGreen(self):
51 if self.green.isChecked():
52 self.color.setGreen(255)
53 else: self.color.setGreen(0)
54
55 self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
56
57 def setBlue(self):
58 if self.blue.isChecked():
59 self.color.setBlue(255)
60 else: self.color.setBlue(0)
61
62 self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
63
64
65
66 app = QtGui.QApplication(sys.argv)
67 tb = ToggleButton()
68 tb.show()
69 app.exec_()
In our example, we create three ToggleButtons. We also create a QWidget. We set the background color of the QWidget to black. The togglebuttons will toggle the red, green and blue parts of the color value. The background color will depend on which togglebuttons we have pressed.
- 这个例子中,我们创建了三个切换按钮。我们也建立了一个QWidget。我们设置QWidget的背景色为黑色。切换按钮将切换颜色值的红、绿和蓝部分。背景颜色将依赖于我们按下的那些切换按钮。
self.color = QtGui.QColor(0, 0, 0)
This is the initial color value. No red, green and blue equals to black. Theoretically speaking, black is not a color after all.
- 这里初始化颜色值,没有红,绿,蓝等于黑。毕竟理论上来说黑不是一种颜色。
self.red = QtGui.QPushButton('Red', self) self.red.setCheckable(True)
To create a ToggleButton, we create a QPushButton and make it checkable by calling setCheckable() method.
- 为了创建一个切换按钮,我们创建一个QPushButton,并且通过调用setCheckable()使它可以被检查。
self.connect(self.red, QtCore.SIGNAL('clicked()'), self.setRed)
We connect a clicked() signal to our user defined method.
- 我们将clicked()信号与我们自己定义的方法连接。
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('cleanlooks'))
I have set the style of the application to cleanlooks. I did it, because the default style for linux, plastique has a design bug. You cannot easily tell whether the ToggleButton is pressed or not. CleanLooks style is better.
- 我已经将应用程序的样式设置为cleanlooks,这么作是因为linux的缺省样式plastique有一个bug,你无法简单的确认切换按钮是否被按下了。
if self.red.isChecked(): self.color.setRed(255) else: self.color.setRed(0)
We check, whether the button is pressed and change the color value accordingly.
- 我们检查按钮是否被按下并且相应的改变颜色值。
self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
To change the background color, we use stylesheets.
- 为了改变背景色,我们使用stylesheets样式表。
Figure: ToggleButton
1.3. QSlider, QLabel
QSlider is a widget that has a simple handle. This handle can be pulled back and forth. This way we are choosing a value for a specific task. Sometimes using a slider is more natural, than simply providing a number or using a spin box. QLabel displays text or image.
- QSlider是一个具有简单的手柄的插件。这个插件可以前后拖动,通过这种方式我们可以为特定的任务选择一个数值。有时使用滑块比简单的提供一个数字或使用输入框更自然。QLabel可以显示文本或图像。
In our example we will show one slider and one label. This time, the label will display an image. The slider will control the label.
- 这个例子里我们会显示一个滑块和一个标签。这次标签会显示一个图像,滑块会控制标签。
1 #!/usr/bin/python
2
3 # slider-label.py
4
5 import sys
6 from PyQt4 import QtGui
7 from PyQt4 import QtCore
8
9
10 class SliderLabel(QtGui.QWidget):
11 def __init__(self, parent=None):
12 QtGui.QWidget.__init__(self, parent)
13
14 self.setGeometry(300, 300, 250, 150)
15 self.setWindowTitle('SliderLabel')
16
17 self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
18 self.slider.setFocusPolicy(QtCore.Qt.NoFocus)
19 self.slider.setGeometry(30, 40, 100, 30)
20 self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), self.changeValue)
21
22
23 self.label = QtGui.QLabel(self)
24 self.label.setPixmap(QtGui.QPixmap('mute.png'))
25 self.label.setGeometry(160, 40, 80, 30)
26
27
28 def changeValue(self, value):
29 pos = self.slider.value()
30
31 if pos == 0:
32 self.label.setPixmap(QtGui.QPixmap('mute.png'))
33 elif pos > 0 and pos <= 30:
34 self.label.setPixmap(QtGui.QPixmap('min.png'))
35 elif pos > 30 and pos < 80:
36 self.label.setPixmap(QtGui.QPixmap('med.png'))
37 else:
38 self.label.setPixmap(QtGui.QPixmap('max.png'))
39
40 app = QtGui.QApplication(sys.argv)
41 icon = SliderLabel()
42 icon.show()
43 app.exec_()
In our example we simulate a volume control. By dragging the handle of a slider, we change a image on the label.
- 这个例子中我们模拟了一个音量控制器,通过拖动滑块我们改变标签中显示的图像。
self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
Here we create a horizontal QSlider.
- 这里我们创建一个水平的QSlider。
self.label = QtGui.QLabel(self) self.label.setPixmap(QtGui.QPixmap('mute.png'))
We create a Qlabel. And set an initial mute image to it.
- 我们创建一个Qlabel,并且设置为缺省的静音图像。
self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), self.changeValue)
We connect the valueChanged signal to the user defined changeValue() method.
- 我们将valueChanged信号与用户定义的changeValue()方法连接。
{{{ pos = self.slider.value() }}} We get the position of the slider by calling the value() method. We change the image on the label accordingly.
- 我们通过调用value()方法获取滑块位置,然后相应的改变标签的图像。
Figure: Slider and Label
1.4. QProgressBar
A progress bar is a widget that is used, when we process lengthy tasks. It is animated so that the user knows, that our task is progressing. The QProgressBar widget provides a horizontal or vertical progress bar in PyQt4 toolkit. The task is divided into steps. The programmer can set the minimum and maximum values for the progress bar. The default values are 0, 99.
进度条是我们处理冗长的任务时使用的组件。它可以生动的展示给用户任务的执行情况。PyQt4工具集中,QProgressBar组件提供水平或垂直的进度条。任务是分步骤的,程序员可以设置进度条的最小和最大值,缺省的取值范围是0-99。
1 #!/usr/bin/python
2
3 # progressbar.py
4
5 import sys
6 from PyQt4 import QtGui
7 from PyQt4 import QtCore
8
9
10 class ProgressBar(QtGui.QWidget):
11 def __init__(self, parent=None):
12 QtGui.QWidget.__init__(self, parent)
13
14 self.setGeometry(300, 300, 250, 150)
15 self.setWindowTitle('ProgressBar')
16
17 self.pbar = QtGui.QProgressBar(self)
18 self.pbar.setGeometry(30, 40, 200, 25)
19
20 self.button = QtGui.QPushButton('Start', self)
21 self.button.setFocusPolicy(QtCore.Qt.NoFocus)
22 self.button.move(40, 80)
23
24 self.connect(self.button, QtCore.SIGNAL('clicked()'), self.onStart)
25
26 self.timer = QtCore.QBasicTimer()
27 self.step = 0;
28
29
30 def timerEvent(self, event):
31 if self.step >= 100:
32 self.timer.stop()
33 return
34 self.step = self.step + 1
35 self.pbar.setValue(self.step)
36
37 def onStart(self):
38 if self.timer.isActive():
39 self.timer.stop()
40 self.button.setText('Start')
41 else:
42 self.timer.start(100, self)
43 self.button.setText('Stop')
44
45
46 app = QtGui.QApplication(sys.argv)
47 icon = ProgressBar()
48 icon.show()
49 app.exec_()
In our example we have a horizontal progress bar and a push button. The push button starts and stops the progress bar.
- 这个例子里我们设置了一个水平的进度条和一个按钮,按钮控制进度条的开始和停止。
self.pbar = QtGui.QProgressBar(self)
QProgressBar constructor.
self.timer = QtCore.QBasicTimer()
To activate the progress bar, we use the timer object.
- 为了激活进度条,我们使用计时器对象。
self.timer.start(100, self)
To launch the timer events, we call the start() method. This method has two parameters. The timeout and the object, which will receive the events.
- 为了开始计时器事件,我们调用start()方法,这个方法有两个参数,超时时间和接受事件的对象。
Each QObject and its descendants has a QObject.timerEvent event handler. In order to react to timer events, we reimplement the event handler.
- 每个QObject对象和它的子对象都有QObject.timerEvent事件处理函数。为了对计时器时间作出反应,我们重载事件处理函数。
ProgressBar Figure: ProgressBar
1.5. QCalendarWidget
The QCalendarWidget provides a monthly based calendar widget. It allows a user to select a date in a simple and intuitive way.
- QCalendarWidget组件提供一个每月的日历组件。它允许用户简单直观的来选择日期。
1 #!/usr/bin/python
2
3 # calendar.py
4
5 import sys
6 from PyQt4 import QtGui
7 from PyQt4 import QtCore
8
9
10 class Calendar(QtGui.QWidget):
11 def __init__(self, parent=None):
12 QtGui.QWidget.__init__(self, parent)
13
14 self.setGeometry(300, 300, 350, 300)
15 self.setWindowTitle('Calendar')
16
17 self.cal = QtGui.QCalendarWidget(self)
18 self.cal.setGridVisible(True)
19 self.cal.move(20, 20)
20 self.connect(self.cal, QtCore.SIGNAL('selectionChanged()'), self.showDate)
21
22
23 self.label = QtGui.QLabel(self)
24 date = self.cal.selectedDate()
25 self.label.setText(str(date.toPyDate()))
26 self.label.move(130, 260)
27
28
29 def showDate(self):
30 date = self.cal.selectedDate()
31 self.label.setText(str(date.toPyDate()))
32
33
34 app = QtGui.QApplication(sys.argv)
35 icon = Calendar()
36 icon.show()
37 app.exec_()
The example has a calendar widget and a label widget. The currently selected date is displayed in the label widget.
- 这个例子有一个日历组件和一个标签组件。当前选择的日期被显示在标签组件中。
self.cal = QtGui.QCalendarWidget(self)
We construct a calendar widget.
- 我们创建一个日历组件。
self.connect(self.cal, QtCore.SIGNAL('selectionChanged()'), self.showDate)
If we select a date from the widget, a selectionChanged() signal is emitted. We connect this method to the user defined showDate() method.
- 如果我们通过组件选择日期,就会产生一个selectionChanged()信号,我们把这个信号连接的我们定义的showDate()方法。
def showDate(self): date = self.cal.selectedDate() self.label.setText(str(date.toPyDate()))
We retrieve the selected date calling the selectedDate() method. Then we transform the date object into string and set it to the label widget.
- 我们通过调用selectedDate()方法接收到日期,然后我们将日期对象转换成字符串并传入标签组件。
Calendar widget
Figure: Calendar widget