PyQt - 我可以在paintEvent中添加一个QWidget吗?

Posted

技术标签:

【中文标题】PyQt - 我可以在paintEvent中添加一个QWidget吗?【英文标题】:PyQt - can I add a QWidget in paintEvent? 【发布时间】:2015-02-12 13:27:05 【问题描述】:

我正在使用 PyQt 制作一个应用程序,除其他外,它以简单的图形图表显示信息。

我已将其作为 QWidget 完成,并重新实现了 paintEvent 方法来进行绘图。下面显示了一个小而非常精简的示例。

from PyQt4.QtCore import * 
from PyQt4.QtGui import *    # sloppy, I know, but done for speed! :-)

class Example(QMainWindow):
    def __init__(self,parent=None):
        super(Example,self).__init__(parent)
        self.init_ui()

    def init_ui(self):
        base=QWidget()
        layout=QVBoxLayout(base)
        self.diagram=Diagram()
        layout.addWidget(self.diagram)
        self.setCentralWidget(base)

class Diagram(QWidget):
    def __init__(self,parent=None):
        super(Diagram,self).__init__(parent)
        self.width=360
        self.height=120
        self.leftMargin=10
        self.topMargin=10

    def paintEvent(self,event=None):
        painter=QPainter(self)
        painter.setWindow(self.leftMargin,self.topMargin,self.width,self.height)
        self.drawConnection(painter, 40, 25, 40, 90)
        self.drawConnection(painter, 40, 90, 40, 110)
        self.drawConnection(painter, 40, 110, 200, 100)
        self.drawItem(painter, 40, 40)
        self.drawItem(painter, 40, 90)
        self.drawState(painter,200,100)

    def drawConnection(self,painter,x0,y0,x1,y1):
        pen=QPen()
        pen.setWidth(4)
        pen.setColor(QColor(50,50,200))
        painter.setPen(pen)
        painter.drawLine(x0,y0,x1,y1)

    def drawItem(self,painter,x,y):
        w=40
        h=30
        r=QRectF(x-(w/2),y-(h/2),w,h)
        painter.drawRoundedRect(r,5.0,5.0)
        grad=QLinearGradient(QPointF(15.0,20.0),QPointF(30.0,30.0))
        pen=QPen()
        pen.setWidth(2)
        pen.setColor(QColor(10,10,10))
        painter.setPen(pen)
        brush=QBrush(QColor(0,200,10))
        painter.setBrush(brush)
        painter.drawRoundedRect(r,5.0,5.0)

    def drawState(self,painter,x,y):
        w=80
        h=60
        r=QRectF(x-(w/2),y-(h/2),w,h)
        pen=QPen()
        pen.setWidth(2)
        pen.setColor(QColor(255,10,10))
        painter.setPen(pen)
        brush=QBrush(QColor(200,200,10))
        painter.setBrush(brush)
        painter.drawPie(r,5040,1440)

if __name__=='__main__':
    app=QApplication(sys.argv)
    example=Example()
    example.show()
    app.exec_()

是否可以添加 QWidget 而不是调用 drawItem?

例如,一个适当样式的 QPushButton 可以代替圆角矩形。

或者,创建一个同时包含小部件和绘制项目的显示的最佳方法是什么?

【问题讨论】:

看起来你只是在绘制一个彩色的 Rect 而不是一个小部件,矩形与 QWidget 不同,因为 QWidget 可以处理很多事件,例如点击事件、keyPressEvent。为什么不直接将子小部件添加到父小部件而不是自己绘制呢?您可以使用 QSS 设置其样式,例如圆角矩形 @CuiHeng 可能我解释的不是很好。我想添加小部件,然后在它们周围绘制我自己的形状。我已经更新了代码示例 - 如何更改 drawItem 为 QPushButton 绘制的矩形,同时仍然在它们周围绘制其他东西? 如果您只想显示和处理图形显示。您可能想尝试使用 [networkx.github.io] 【参考方案1】:

我使用 QSS 编写了一个圆形子小部件示例。

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys


ROUNDED_STYLE_SHEET = """QPushButton 
     background-color: red;
     border-style: outset;
     border-width: 2px;
     border-radius: 10px;
     border-color: beige;
     font: bold 14px;
     min-width: 10em;
     padding: 6px;
 
"""


class MyWidget(QWidget):
    def __init__(self, parent=None):
        super(MyWidget, self).__init__(parent)
        self.mChildWidget = QPushButton(self)
        self.resize(600, 400)
        self.mChildWidget.resize(120, 80)
        self.mChildWidget.move(300, 200)
        self.mChildWidget.setStyleSheet(ROUNDED_STYLE_SHEET)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MyWidget()
    w.show()
    app.exec_()

【讨论】:

如何使用这个小部件来代替我正在绘制的绿色矩形?

以上是关于PyQt - 我可以在paintEvent中添加一个QWidget吗?的主要内容,如果未能解决你的问题,请参考以下文章

PyQt5 使用 keyPressEvent() 触发paintEvent()

如何在不使用paintEvent的情况下旋转PyQt5 QPushButton?

在 PyQt5 和 PySide2 中覆盖paintEvent

在 Unix shell 中添加一列数字

Prisma:如何在查询返回中添加一列?

使用 QPainter 和 paintEvent 在 PYQT5 中的 QLabel 中包含的 Pixmap 上绘制圆圈