简体   繁体   English

在 PyQt GUI 中集成 QPainter

[英]Integrating QPainter in PyQt GUI

I'm trying to use QPainter-made object along with native widgets of PyQt in one layout and having a difficulty doing so.我正在尝试在一个布局中使用 QPainter 制造的 object 以及 PyQt 的本机小部件,但这样做有困难。

I've tried using addWidget() to add it to the layout but no luck.我尝试使用addWidget()将其添加到布局中,但没有运气。

class window(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(600, 500)
        self.setWindowTitle('GUI 2.0')

        #LCD
        self.lcd = QLCDNumber()
        self.lcd.setFixedHeight(100)

        #Slider
        self.slider = QSlider(Qt.Horizontal)
        self.slider.setMaximum(40)
        self.slider.setMinimum(0)
        self.slider.valueChanged.connect(self.progress)

        #Push button
        pb = QPushButton('Button', self)
        pb.clicked.connect(self.button)

        #Progress Bar
        self.pbar = QProgressBar(self)
        self.pbar.setGeometry(30, 40, 200, 25)
        self.pbar.setTextVisible(False)

        #Qpainter
        painter = QPainter()
        painter.setPen(QPen(Qt.black, 5, Qt.SolidLine))
        painter.setBrush(QBrush(Qt.green, Qt.DiagCrossPattern))
        painter.drawRect(100, 15, 400,200)

        #Grid Layout 
        layout = QGridLayout()
        layout.addWidget(self.lcd, 1, 1)
        layout.addWidget(self.slider, 2, 1)
        layout.addWidget(pb, 2, 2)
        layout.addWidget(self.pbar, 0, 1)
        layout.addWidget(painter) # doesn't work!

        self.setLayout(layout)

My aim is for something like this where the slider will eventually change the water level in the tank and the button will reset the slider value and therefore empty the tank:我的目标是这样的,slider 最终会改变水箱中的水位,按钮将重置 slider 值并因此清空水箱:

水箱

水箱

Whereas I have something like this:而我有这样的事情:

自制

How can I add the painter object to the layout?如何将画家 object 添加到布局中?

QPainter is not a widget but only paints on a device (QWidget, QImage, QPixmap, etc.), so in your case you must create a custom widget where in the paintEvent method the tank is painted QPainter 不是一个小部件,而只是在设备上绘画(QWidget、QImage、QPixmap 等),因此在您的情况下,您必须创建一个自定义小部件,在 paintEvent 方法中绘制坦克

from PyQt5 import QtCore, QtGui, QtWidgets


class TankWidget(QtWidgets.QWidget):
    progressChanged = QtCore.pyqtSignal(float)

    def __init__(self, parent=None):
        super().__init__(parent)

        self._progress = 0.0

    @QtCore.pyqtProperty(float, notify=progressChanged)
    def progress(self):
        return self._progress

    @progress.setter
    def progress(self, p):
        if 0 <= p <= 1.0:
            self._progress = p
            self.progressChanged.emit(p)
            self.update()

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)
        height = self.progress * self.height()

        r = QtCore.QRect(0, self.height() - height, self.width(), height)
        painter.fillRect(r, QtGui.QBrush(QtCore.Qt.blue))
        pen = QtGui.QPen(QtGui.QColor("red"), 10)
        painter.setPen(pen)
        painter.drawRect(self.rect())

    def sizeHint(self):
        return QtCore.QSize(100, 100)


class Widget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.resize(600, 500)
        self.setWindowTitle("GUI 2.0")

        self.tank = TankWidget()
        self.progressbar = QtWidgets.QProgressBar()
        self.lcd = QtWidgets.QLCDNumber()
        self.lcd.setFixedHeight(100)
        self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, maximum=101)
        self.button = QtWidgets.QPushButton("Button")

        self.slider.valueChanged.connect(self.on_value_changed)

        lay = QtWidgets.QGridLayout(self)
        lay.addWidget(self.tank, 0, 0, 2, 1)
        lay.addWidget(QtWidgets.QLabel("Tank", alignment=QtCore.Qt.AlignCenter), 2, 0)
        lay.addWidget(self.progressbar, 0, 1)
        lay.addWidget(self.lcd, 1, 1)
        lay.addWidget(self.slider, 2, 1)
        lay.addWidget(
            QtWidgets.QLabel(
                pixmap=QtGui.QPixmap("warning.png"), alignment=QtCore.Qt.AlignCenter
            ),
            0,
            2,
            2,
            1,
        )
        lay.addWidget(self.button, 2, 2)

        self.setFixedHeight(self.sizeHint().height())

        self.slider.setValue(40)

    @QtCore.pyqtSlot()
    def on_value_changed(self):
        progress = self.slider.value() * 1.0 / self.slider.maximum()
        self.tank.progress = progress
        self.progressbar.setValue(self.slider.value())
        self.lcd.display(self.slider.value())


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM