这是PyQt6教程。本教程适合初学者和中级程序员。阅读本教程后,您将能够编写非平凡的PyQt6应用程序。
代码示例可在本站下载:教程源代码
目录
- 引言
- 日期和时间
- 第一个工程
- 菜单与工具栏
- 布局管理
- 事件和信号
- 对话框
- 控件
- 拖放
- 绘画
- 自定义控件
- 俄罗斯方块
自定义控件
lPyQt6有一套丰富的控件。然而,没有一个工具包可以提供程序员在应用程序中可能需要的所有控件。工具包通常只提供最常见的控件,如按钮、文本小部件或滑块。如果需要一个更专业的控件,我们必须自己创建。
自定义控件是使用工具包提供的绘图工具创建的。有两种基本可能性:程序员可以修改或增强现有的控件,也可以从头开始创建自定义控件。
PyQt6 烧录控件
这是一个我们可以在Nero、K3B或其他CD/DVD刻录软件中看到的控件。
#!/usr/bin/python """ ZetCode PyQt6 tutorial In this example, we create a custom widget. Author: Jan Bodnar Website: zetcode.com """ from PyQt6.QtWidgets import (QWidget, QSlider, QApplication, QHBoxLayout, QVBoxLayout) from PyQt6.QtCore import QObject, Qt, pyqtSignal from PyQt6.QtGui import QPainter, QFont, QColor, QPen import sys class Communicate(QObject): updateBW = pyqtSignal(int) class BurningWidget(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setMinimumSize(1, 30) self.value = 75 self.num = [75, 150, 225, 300, 375, 450, 525, 600, 675] def setValue(self, value): self.value = value def paintEvent(self, e): qp = QPainter() qp.begin(self) self.drawWidget(qp) qp.end() def drawWidget(self, qp): MAX_CAPACITY = 700 OVER_CAPACITY = 750 font = QFont('Serif', 7, QFont.Weight.Light) qp.setFont(font) size = self.size() w = size.width() h = size.height() step = int(round(w / 10)) till = int(((w / OVER_CAPACITY) * self.value)) full = int(((w / OVER_CAPACITY) * MAX_CAPACITY)) if self.value >= MAX_CAPACITY: qp.setPen(QColor(255, 255, 255)) qp.setBrush(QColor(255, 255, 184)) qp.drawRect(0, 0, full, h) qp.setPen(QColor(255, 175, 175)) qp.setBrush(QColor(255, 175, 175)) qp.drawRect(full, 0, till - full, h) else: qp.setPen(QColor(255, 255, 255)) qp.setBrush(QColor(255, 255, 184)) qp.drawRect(0, 0, till, h) pen = QPen(QColor(20, 20, 20), 1, Qt.PenStyle.SolidLine) qp.setPen(pen) qp.setBrush(Qt.BrushStyle.NoBrush) qp.drawRect(0, 0, w - 1, h - 1) j = 0 for i in range(step, 10 * step, step): qp.drawLine(i, 0, i, 5) metrics = qp.fontMetrics() fw = metrics.horizontalAdvance(str(self.num[j])) x, y = int(i - fw/2), int(h / 2) qp.drawText(x, y, str(self.num[j])) j = j + 1 class Example(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): OVER_CAPACITY = 750 sld = QSlider(Qt.Orientations.Horizontal, self) sld.setFocusPolicy(Qt.FocusPolicy.NoFocus) sld.setRange(1, OVER_CAPACITY) sld.setValue(75) sld.setGeometry(30, 40, 150, 30) self.c = Communicate() self.wid = BurningWidget() self.c.updateBW[int].connect(self.wid.setValue) sld.valueChanged[int].connect(self.changeValue) hbox = QHBoxLayout() hbox.addWidget(self.wid) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.setGeometry(300, 300, 390, 210) self.setWindowTitle('Burning widget') self.show() def changeValue(self, value): self.c.updateBW.emit(value) self.wid.repaint() def main(): app = QApplication(sys.argv) ex = Example() sys.exit(app.exec()) if __name__ == '__main__': main()在我们的示例中,我们有一个和一个自定义控件。滑块控制自定义控件。此控件以图形方式显示介质的总容量和可用空间。我们自定义控件的最小值为1,最大值为OVER_capacity。如果我们达到值MAX_CAPACITY,我们就开始用红色绘制。这通常表示过度烧录。
刻录控件放置在窗口底部。这是通过使用一个和一个来实现的
class BurningWidget(QWidget): def __init__(self): super().__init__()刻录控件是基于基础控件的。
self.setMinimumSize(1, 30)我们更改控件的最小大小(高度)。默认值对我们来说有点小。
font = QFont('Serif', 7, QFont.Weight.Light) qp.setFont(font)我们使用比默认字体更小的字体。这更符合我们的需要。
size = self.size() w = size.width() h = size.height() step = int(round(w / 10)) till = int(((w / OVER_CAPACITY) * self.value)) full = int(((w / OVER_CAPACITY) * MAX_CAPACITY))我们动态地绘制控件。窗口越大,烧录控件就越大,反之亦然。这就是为什么我们必须计算绘制自定义控件的窗口大小。该参数决定了要绘制的总大小。此值来自滑块控件。这是整个地区的一部分。该参数决定了我们开始用红色绘制的点。直到满
实际绘图由三个步骤组成。我们画黄色或红黄相间的矩形。然后我们绘制垂直线,将控件划分为几个部分。最后,我们得出表示介质容量的数字。
metrics = qp.fontMetrics() fw = metrics.horizontalAdvance(str(self.num[j])) x, y = int(i - fw/2), int(h / 2) qp.drawText(x, y, str(self.num[j]))我们使用字体度量来绘制文本。我们必须知道文本的宽度,以便将其居中放置在垂直线周围。
def changeValue(self, value): self.c.updateBW.emit(value) self.wid.repaint()当我们移动滑块时,会调用该方法。在方法内部,我们发送一个带有参数的自定义信号。该参数是滑块的当前值。该值稍后用于计算要绘制的Burning控件的容量。然后重新绘制自定义控件。
在PyQt6教程的这一部分中,我们创建了一个自定义控件。