PyQt FAQ Widgets

Материал из Wiki.crossplatform.ru

(Различия между версиями)
Перейти к: навигация, поиск
(Новая: 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 progra...)
(Удалено по требованию автора...)
 
Строка 1: Строка 1:
-
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.
 
-
== 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 <i>stateChanged()</i>.
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
 
-
# checkbox.py
 
-
 
-
import sys
 
-
from PyQt4 import QtGui
 
-
from PyQt4 import QtCore
 
-
 
-
 
-
class CheckBox(QtGui.QWidget):
 
-
    def __init__(self, parent=None):
 
-
        QtGui.QWidget.__init__(self, parent)
 
-
 
-
        self.setGeometry(300, 300, 250, 150)
 
-
        self.setWindowTitle('Checkbox')
 
-
 
-
        self.cb = QtGui.QCheckBox('Show title', self)
 
-
        self.cb.setFocusPolicy(QtCore.Qt.NoFocus)
 
-
        self.cb.move(10, 10)
 
-
        self.cb.toggle();
 
-
        self.connect(self.cb, QtCore.SIGNAL('stateChanged(int)'), self.changeTitle)
 
-
 
-
    def changeTitle(self, value):
 
-
        if self.cb.isChecked():
 
-
            self.setWindowTitle('Checkbox')
 
-
        else:
 
-
            self.setWindowTitle('')
 
-
 
-
app = QtGui.QApplication(sys.argv)
 
-
icon = CheckBox()
 
-
icon.show()
 
-
app.exec_()
 
-
</source>
 
-
 
-
In our example, we will create a checkbox that will toggle the window title.
 
-
 
-
<source lang="python">
 
-
self.cb = QtGui.QCheckBox('Show title', self)
 
-
</source>
 
-
 
-
This is the <i>QCheckBox</i> constructor.
 
-
 
-
<source lang="python">
 
-
self.cb.setFocusPolicy(QtCore.Qt.NoFocus)
 
-
</source>
 
-
 
-
We connect the user defined <i>changeTitle()</i> method to the <i>stateChanged()</i> signal.
 
-
The <i>changeTitle()</i> method will toggle the window title.
 
-
 
-
<source lang="python">
 
-
self.connect(self.cb, QtCore.SIGNAL('stateChanged(int)'), self.changeTitle)
 
-
</source>
 
-
 
-
By default, the <i>QCheckBox</i> 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 <i>Qt.NoFocus</i>.
 
-
 
-
<source lang="python">
 
-
self.cb.toggle();
 
-
</source>
 
-
 
-
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.
 
-
 
-
[[image: pyqt_faq_checkbox.jpg | center]]
 
-
 
-
== ToggleButton ==
 
-
PyQt4 has no widget for a ToggleButton. To create a ToggleButton, we use a <i>QPushButton</i> 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.
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# togglebutton.py
 
-
 
-
import sys
 
-
from PyQt4 import QtGui
 
-
from PyQt4 import QtCore
 
-
 
-
 
-
class ToggleButton(QtGui.QWidget):
 
-
    def __init__(self, parent=None):
 
-
        QtGui.QWidget.__init__(self, parent)
 
-
 
-
        self.color = QtGui.QColor(0, 0, 0)
 
-
 
-
        self.setGeometry(300, 300, 280, 170)
 
-
        self.setWindowTitle('ToggleButton')
 
-
 
-
        self.red = QtGui.QPushButton('Red', self)
 
-
        self.red.setCheckable(True)
 
-
        self.red.move(10, 10)
 
-
 
-
        self.connect(self.red, QtCore.SIGNAL('clicked()'), self.setRed)
 
-
 
-
        self.green = QtGui.QPushButton('Green', self)
 
-
        self.green.setCheckable(True)
 
-
        self.green.move(10, 60)
 
-
 
-
        self.connect(self.green, QtCore.SIGNAL('clicked()'), self.setGreen)
 
-
 
-
        self.blue = QtGui.QPushButton('Blue', self)
 
-
        self.blue.setCheckable(True)
 
-
        self.blue.move(10, 110)
 
-
 
-
        self.connect(self.blue, QtCore.SIGNAL('clicked()'), self.setBlue)
 
-
 
-
        self.square = QtGui.QWidget(self)
 
-
        self.square.setGeometry(150, 20, 100, 100)
 
-
        self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
 
-
 
-
        QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('cleanlooks'))
 
-
 
-
    def setRed(self):
 
-
        if self.red.isChecked():
 
-
            self.color.setRed(255)
 
-
        else: self.color.setRed(0)
 
-
 
-
        self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
 
-
 
-
    def setGreen(self):
 
-
        if self.green.isChecked():
 
-
            self.color.setGreen(255)
 
-
        else: self.color.setGreen(0)
 
-
 
-
        self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
 
-
 
-
    def setBlue(self):
 
-
        if self.blue.isChecked():
 
-
            self.color.setBlue(255)
 
-
        else: self.color.setBlue(0)
 
-
 
-
        self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
 
-
 
-
 
-
 
-
app = QtGui.QApplication(sys.argv)
 
-
tb = ToggleButton()
 
-
tb.show()
 
-
app.exec_()
 
-
</source>
 
-
 
-
In our example, we create three ToggleButtons. We also create a <i>QWidget</i>. 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. 
 
-
 
-
<source lang="python">
 
-
self.color = QtGui.QColor(0, 0, 0)
 
-
</source>
 
-
 
-
This is the initial color value. No red, green and blue equals to black. Theoretically speaking, black is not a color after all.
 
-
 
-
<source lang="python">
 
-
self.red = QtGui.QPushButton('Red', self)
 
-
self.red.setCheckable(True)
 
-
</source>
 
-
 
-
To create a ToggleButton, we create a <i>QPushButton</i> and make it checkable by calling <i>setCheckable()</i> method.
 
-
 
-
<source lang="python">
 
-
self.connect(self.red, QtCore.SIGNAL('clicked()'), self.setRed)
 
-
</source>
 
-
 
-
We connect a <i>clicked()</i> signal to our user defined method.
 
-
 
-
<source lang="python">
 
-
QtGui.QApplication.setStyle(QtGui.QStyleFactory.create('cleanlooks'))
 
-
 
-
</source>
 
-
 
-
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.
 
-
 
-
<source lang="python">
 
-
if self.red.isChecked():
 
-
    self.color.setRed(255)
 
-
else: self.color.setRed(0)
 
-
</source>
 
-
 
-
We check, whether the button is pressed and change the color value accordingly.
 
-
 
-
<source lang="python">
 
-
self.square.setStyleSheet("QWidget { background-color: %s }" % self.color.name())
 
-
</source>
 
-
 
-
To change the background color, we use stylesheets.
 
-
 
-
[[image: pyqt_faq_togglebutton.jpg | center]]
 
-
 
-
== 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.
 
-
 
-
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.
 
-
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# slider-label.py
 
-
 
-
import sys
 
-
from PyQt4 import QtGui
 
-
from PyQt4 import QtCore
 
-
 
-
 
-
class SliderLabel(QtGui.QWidget):
 
-
    def __init__(self, parent=None):
 
-
        QtGui.QWidget.__init__(self, parent)
 
-
 
-
        self.setGeometry(300, 300, 250, 150)
 
-
        self.setWindowTitle('SliderLabel')
 
-
 
-
        self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
 
-
        self.slider.setFocusPolicy(QtCore.Qt.NoFocus)
 
-
        self.slider.setGeometry(30, 40, 100, 30)
 
-
        self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), self.changeValue)
 
-
 
-
 
-
        self.label = QtGui.QLabel(self)
 
-
        self.label.setPixmap(QtGui.QPixmap('mute.png'))
 
-
        self.label.setGeometry(160, 40, 80, 30)
 
-
 
-
 
-
    def changeValue(self, value):
 
-
        pos = self.slider.value()
 
-
 
-
        if pos == 0:
 
-
            self.label.setPixmap(QtGui.QPixmap('mute.png'))
 
-
        elif pos > 0 and pos <= 30:
 
-
            self.label.setPixmap(QtGui.QPixmap('min.png'))
 
-
        elif pos > 30 and pos < 80:
 
-
            self.label.setPixmap(QtGui.QPixmap('med.png'))
 
-
        else:
 
-
            self.label.setPixmap(QtGui.QPixmap('max.png'))
 
-
 
-
app = QtGui.QApplication(sys.argv)
 
-
icon = SliderLabel()
 
-
icon.show()
 
-
app.exec_()
 
-
</source>
 
-
 
-
In our example we simulate a volume control. By dragging the handle of a slider, we change a image on the label.
 
-
 
-
<source lang="python">
 
-
self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
 
-
</source>
 
-
 
-
Here we create a horizontal <i>QSlider</i>.
 
-
 
-
<source lang="python">
 
-
self.label = QtGui.QLabel(self)
 
-
self.label.setPixmap(QtGui.QPixmap('mute.png'))
 
-
</source>
 
-
 
-
We create a <i>Qlabel</i>. And set an initial mute image to it.
 
-
 
-
<source lang="python">
 
-
self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'), self.changeValue)
 
-
</source>
 
-
 
-
We connect the <i>valueChanged</i> signal to the user defined <i>changeValue()</i> method.
 
-
 
-
<source lang="python">
 
-
pos = self.slider.value()
 
-
</source>
 
-
 
-
We get the position of the slider by calling the <i>value()</i> method. We change the image on the label accordingly.
 
-
 
-
[[image: pyqt_faq_sliderlabel.jpg | center]]
 
-
 
-
== 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 <i>QProgressBar</i> 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.
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# progressbar.py
 
-
 
-
import sys
 
-
from PyQt4 import QtGui
 
-
from PyQt4 import QtCore
 
-
 
-
 
-
class ProgressBar(QtGui.QWidget):
 
-
    def __init__(self, parent=None):
 
-
        QtGui.QWidget.__init__(self, parent)
 
-
 
-
        self.setGeometry(300, 300, 250, 150)
 
-
        self.setWindowTitle('ProgressBar')
 
-
 
-
        self.pbar = QtGui.QProgressBar(self)
 
-
        self.pbar.setGeometry(30, 40, 200, 25)
 
-
 
-
        self.button = QtGui.QPushButton('Start', self)
 
-
        self.button.setFocusPolicy(QtCore.Qt.NoFocus)
 
-
        self.button.move(40, 80)
 
-
 
-
        self.connect(self.button, QtCore.SIGNAL('clicked()'), self.onStart)
 
-
 
-
        self.timer = QtCore.QBasicTimer()
 
-
        self.step = 0;
 
-
 
-
 
-
    def timerEvent(self, event):
 
-
        if self.step >= 100:
 
-
            self.timer.stop()
 
-
            return
 
-
        self.step = self.step + 1
 
-
        self.pbar.setValue(self.step)
 
-
 
-
    def onStart(self):
 
-
        if self.timer.isActive():
 
-
            self.timer.stop()
 
-
            self.button.setText('Start')
 
-
        else:
 
-
            self.timer.start(100, self)
 
-
            self.button.setText('Stop')
 
-
 
-
 
-
app = QtGui.QApplication(sys.argv)
 
-
icon = ProgressBar()
 
-
icon.show()
 
-
app.exec_()
 
-
</source>
 
-
 
-
In our example we have a horizontal progress bar and a push button. The push button starts and stops the progress bar.
 
-
 
-
<source lang="python">
 
-
self.pbar = QtGui.QProgressBar(self)
 
-
</source>
 
-
 
-
<i>QProgressBar constructor.</i>
 
-
 
-
<source lang="python">
 
-
self.timer = QtCore.QBasicTimer()
 
-
</source>
 
-
 
-
To activate the progress bar, we use the timer object.
 
-
 
-
<source lang="python">
 
-
self.timer.start(100, self)
 
-
</source>
 
-
 
-
To launch the timer events, we call the <i>start()</i> method. This method has two parameters. The timeout and the object, which will receive the events.
 
-
 
-
<source lang="python">
 
-
def timerEvent(self, event):
 
-
    if self.step >= 100:
 
-
        self.timer.stop()
 
-
        return
 
-
    self.step = self.step + 1
 
-
    self.pbar.setValue(self.step)
 
-
</source>
 
-
 
-
Each <i>QObject</i> and its descendants has a <i>QObject.timerEvent</i> event handler. In order to react to timer events, we reimplement the event handler.
 
-
 
-
[[image: pyqt_faq_progressbar.jpg | center]]
 
-
 
-
== QCalendarWidget ==
 
-
The <i>QCalendarWidget</i>  provides a monthly based calendar widget. It allows a user to select a date in a simple and intuitive way.
 
-
<source lang="python">
 
-
#!/usr/bin/python
 
-
# calendar.py
 
-
 
-
import sys
 
-
from PyQt4 import QtGui
 
-
from PyQt4 import QtCore
 
-
 
-
 
-
class Calendar(QtGui.QWidget):
 
-
    def __init__(self, parent=None):
 
-
        QtGui.QWidget.__init__(self, parent)
 
-
 
-
        self.setGeometry(300, 300, 350, 300)
 
-
        self.setWindowTitle('Calendar')
 
-
 
-
        self.cal = QtGui.QCalendarWidget(self)
 
-
        self.cal.setGridVisible(True)
 
-
        self.cal.move(20, 20)
 
-
        self.connect(self.cal, QtCore.SIGNAL('selectionChanged()'), self.showDate)
 
-
 
-
 
-
        self.label = QtGui.QLabel(self)
 
-
        date = self.cal.selectedDate()
 
-
        self.label.setText(str(date.toPyDate()))
 
-
        self.label.move(130, 260)
 
-
 
-
 
-
    def showDate(self):
 
-
        date = self.cal.selectedDate()
 
-
        self.label.setText(str(date.toPyDate()))
 
-
 
-
 
-
app = QtGui.QApplication(sys.argv)
 
-
icon = Calendar()
 
-
icon.show()
 
-
app.exec_()
 
-
</source>
 
-
 
-
The example has a calendar widget and a label widget. The currently selected date is displayed in the label widget.
 
-
 
-
<source lang="python">
 
-
self.cal = QtGui.QCalendarWidget(self)
 
-
</source>
 
-
 
-
We construct a calendar widget.
 
-
 
-
<source lang="python">
 
-
self.connect(self.cal, QtCore.SIGNAL('selectionChanged()'), self.showDate)
 
-
</source>
 
-
 
-
If we select a date from the widget, a <i>selectionChanged()</i> signal is emitted. We connect this method to the user defined <i>showDate()</i> method.
 
-
 
-
<source lang="python">
 
-
def showDate(self):
 
-
    date = self.cal.selectedDate()
 
-
    self.label.setText(str(date.toPyDate()))
 
-
</source>
 
-
 
-
We retrieve the selected date calling the <i>selectedDate()</i> method. Then we transform the date object into string and set it to the label widget.
 
-
 
-
[[image: pyqt_faq_calendar.jpg | center]]
 
-
 
-
[[Категория:Qt]]
 
-
[[Категория:Python]]
 

Текущая версия на 11:55, 7 апреля 2009