pyqt5——控制元件1
控制元件1
控制元件就像是應用這座房子的一塊塊磚。PyQt5有很多的控制元件,比如按鈕,單選框,滑動條,複選框等等。在本章,我們將介紹一些很有用的控制元件:QCheckBox
,ToggleButton
,QSlider
,QProgressBar
和QCalendarWidget
。
QCheckBox
QCheckBox
元件有倆狀態:開和關。通常跟標籤一起使用,用在啟用和關閉一些選項的場景。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial 歡迎加入群`923 414 804`與我一起學習 In this example, a QCheckBox widget is used to toggle the title of a window. Author: Jan Bodnar Website: zetcode.com Last edited: August 2017 """ from PyQt5.QtWidgets import QWidget, QCheckBox, QApplication from PyQt5.QtCore import Qt import sys 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_())
這個例子中,有一個能切換視窗標題的單選框。
cb = QCheckBox('Show title', self)
這個是QCheckBox
的構造器。
cb.toggle()
要設定視窗標題,我們就要檢查單選框的狀態。預設情況下,視窗沒有標題,單選框未選中。
cb.stateChanged.connect(self.changeTitle)
把changeTitle()
方法和stateChanged
訊號關聯起來。這樣,changeTitle()
就能切換視窗標題了。
def changeTitle(self, state): if state == Qt.Checked: self.setWindowTitle('QCheckBox') else: self.setWindowTitle('')
控制元件的狀態是由changeTitle()
方法控制的,如果空間被選中,我們就給視窗新增一個標題,如果沒被選中,就清空標題。
程式展示:
切換按鈕
切換按鈕就是QPushButton
的一種特殊模式。 它只有兩種狀態:按下和未按下。我們再點選的時候切換兩種狀態,有很多場景會使用到這個功能。
#!/usr/bin/python3 # -*- coding: utf-8 -*- """ ZetCode PyQt5 tutorial In this example, we create three toggle buttons. They will control the background color of a QFrame. Author: Jan Bodnar Website: zetcode.com Last edited: August 2017 """ from PyQt5.QtWidgets import (QWidget, QPushButton, QFrame, QApplication) from PyQt5.QtGui import QColor import sys 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) greenb = QPushButton('Green', self) greenb.setCheckable(True) greenb.move(10, 60) greenb.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
的背景設定為黑色。點選不同的切換按鈕,背景色會在紅、綠、藍之間切換(而且能看到顏色合成的效果,而不是單純的顏色覆蓋)。
self.col = QColor(0, 0, 0)
設定顏色為黑色。
redb = QPushButton('Red', self)
redb.setCheckable(True)
redb.move(10, 10)
建立一個QPushButton
,然後呼叫它的setCheckable()
的方法就把這個按鈕程式設計了切換按鈕。
redb.clicked[bool].connect(self.setColor)
把點選訊號和我們定義好的函式關聯起來,這裡是把點選事件轉換成布林值。
source = self.sender()
獲取被點選的按鈕。
if source.text() == "Red":
self.col.setRed(val)
如果是標籤為“red”的按鈕被點選,就把顏色更改為預設好的對應顏色。
self.square.setStyleSheet("QFrame { background-color: %s }" %
self.col.name())
使用樣式表(就是CSS的SS)改變背景色
程式展示:
滑塊
QSlider
是個有一個小滑塊的元件,這個小滑塊能拖著前後滑動,這個經常用於修改一些具有範圍的數值,比文字框或者點選增加減少的文字框(spin box)方便多了。
本例用一個滑塊和一個標籤展示。標籤為一個圖片,滑塊控制標籤(的值)。
先弄個叫mute.png的靜音圖標準備著。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
This example shows a QSlider widget.
Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
"""
from PyQt5.QtWidgets import (QWidget, QSlider,
QLabel, QApplication)
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap
import sys
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_())
這裡是模擬的音量控制器。拖動滑塊,能改變標籤位置的圖片。
sld = QSlider(Qt.Horizontal, self)
建立一個水平的QSlider
。
self.label = QLabel(self)
self.label.setPixmap(QPixmap('mute.png'))
建立一個QLabel
元件並給它設定一個靜音圖示。
sld.valueChanged[int].connect(self.changeValue)
把valueChanged
訊號跟changeValue()
方法關聯起來。
if value == 0:
self.label.setPixmap(QPixmap('mute.png'))
...
根據音量值的大小更換標籤位置的圖片。這段程式碼是:如果音量為0,就把圖片換成 mute.png。
程式展示:
進度條
進度條是用來展示任務進度的(我也不想這樣說話)。它的滾動能讓使用者瞭解到任務的進度。QProgressBar
元件提供了水平和垂直兩種進度條,進度條可以設定最大值和最小值,預設情況是0~99。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
This example shows a QProgressBar widget.
Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
"""
from PyQt5.QtWidgets import (QWidget, QProgressBar,
QPushButton, QApplication)
from PyQt5.QtCore import QBasicTimer
import sys
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_())
我們建立了一個水平的進度條和一個按鈕,這個按鈕控制進度條的開始和停止。
self.pbar = QProgressBar(self)
新建一個QProgressBar
構造器。
self.timer = QtCore.QBasicTimer()
用時間控制進度條。
self.timer.start(100, self)
呼叫start()
方法載入一個時間事件。這個方法有兩個引數:過期時間和事件接收者。
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()
事件處理函式。為了觸發事件,我們過載了這個方法。
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()
方法是用來控制開始和停止的。
程式展示:
日曆
QCalendarWidget
提供了基於月份的日曆外掛,十分簡易而且直觀。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
This example shows a QCalendarWidget widget.
Author: Jan Bodnar
Website: zetcode.com
Last edited: August 2017
"""
from PyQt5.QtWidgets import (QWidget, QCalendarWidget,
QLabel, QApplication, QVBoxLayout)
from PyQt5.QtCore import QDate
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
vbox = QVBoxLayout(self)
cal = QCalendarWidget(self)
cal.setGridVisible(True)
cal.clicked[QDate].connect(self.showDate)
vbox.addWidget(cal)
self.lbl = QLabel(self)
date = cal.selectedDate()
self.lbl.setText(date.toString())
vbox.addWidget(self.lbl)
self.setLayout(vbox)
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_())
這個例子有日期元件和標籤元件組成,標籤顯示被選中的日期。
cal = QCalendarWidget(self)
建立一個QCalendarWidget
。
cal.clicked[QDate].connect(self.showDate)
選擇一個日期時,QDate
的點選訊號就觸發了,把這個訊號和我們自己定義的showDate()
方法關聯起來。
def showDate(self, date):
self.lbl.setText(date.toString())
使用selectedDate()
方法獲取選中的日期,然後把日期物件轉成字串,在標籤裡面顯示出來。
程式展示: