簡體   English   中英

PyQt5:為什么QGroupBox的默認樣式在繪畫時會消失?

[英]PyQt5: Why does the default style of a QGroupBox disappear when painting?

我的應用程序使用排列在 QGridLayout 中的各種 QGroupBox 來顯示信息。 我希望其中一個顯示我繪制的自定義形狀。 由於我希望形狀是 GroupBox 並且很難獲得小部件相對於窗口的位置,因此我決定將 GroupBox 子類化並將繪制事件添加到子類中。 這很好用,但是它完全消除了 GroupBox 的默認樣式,包括標題。

下面的代碼創建了一個帶有兩個 GroupBox 的簡單窗口,一個使用標准類,一個使用子類中的繪制事件。 您應該看到右邊的只有繪制的矩形,沒有 GroupBox 樣式。

如果您注釋掉繪制事件,則 GroupBox 將照常顯示。 為什么會發生這種情況,我應該怎么做才能保持 GroupBox 風格? 是否有另一種方法可以在不使用子類中的繪制事件的 GroupBox 中使用畫家?

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *


class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        ## Set up Window layout
        super(MainWindow, self).__init__(*args, **kwargs)

        self.layout = QGridLayout()
        self.setLayout(self.layout)
        self.setGeometry(300, 50, 1000, 700)

        leftGroup = QGroupBox('Left Group')
        self.layout.addWidget(leftGroup, 0, 0)

        rightGroup = RightGroup()
        self.layout.addWidget(rightGroup, 0, 1)


class RightGroup(QGroupBox):
    def __init__(self):
        super(RightGroup, self).__init__('Right Group')

    def paintEvent(self, event):
        painter = QPainter(self)

        # Paint Style
        painter.setPen(QPen(Qt.black, .5, Qt.SolidLine))

        painter.drawRect(QRectF(0, 0, self.width(), self.height()))


if __name__ == '__main__':
    ## Creates a QT Application
    app = QApplication([])

    ## Creates a window
    window = MainWindow()

    ## Shows the window
    window.show()
    app.exec_()

啟用繪制事件的窗口

帶有繪制事件的窗口被注釋掉

您正在覆蓋整個繪畫,“覆蓋”意味着您忽略默認行為。

標准 Qt 小部件的paintEvent()的默認行為導致繪制該小部件(無論是按鈕、標簽、組框等)。 如果您只是覆蓋它,則該小部件將永遠不會被繪制,除非您調用默認實現(即: super().paintEvent(event) )。

例如,考慮以下情況:

class RightGroup(QGroupBox):
    pass

這將正確顯示一個正常的組框。

現在,這個:

class RightGroup(QGroupBox):
    def paintEvent(self, event):
        pass

不會顯示任何內容,因為您明確忽略了默認繪畫行為。 要“恢復”它添加自定義繪圖:

class RightGroup(QGroupBox):
    def paintEvent(self, event):
        super().paintEvent(event)
        qp = QPainter(self)
        qp.drawRect(self.rect().adjusted(0, 0, -1, -1)

注意:除非您使用抗鋸齒且筆寬小於或等於 0.5,否則應始終將對象矩形的右/下邊緣限制為小於或等於筆寬一半的整數。 這就是上面adjusted(0, 0, -1, -1)的原因。 對於您上面的代碼,它將是QRectF(0, 0, self.width() - 1, self.height() - 1)

也就是說,您可能希望該組框內繪圖,因此,更好的解決方案是為該組框的內容創建一個子類,將其添加到該組框並覆蓋該子類的繪制事件。

class MainWindow(QWidget):
    def __init__(self, *args, **kwargs):
        # ...
        rightGroup = QGroupBox('Right Group')
        self.layout.addWidget(rightGroup, 0, 1)

        rightLayout = QVBoxLayout(rightGroup)
        rightLayout.addWidget(Canvas())


class Canvas(QWidget):
    def __init__(self):
        super().__init__()
        self.path = QPainterPath()

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.path.moveTo(event.pos())

    def mouseMoveEvent(self, event):
        # note: here we use "buttons", not "button".
        if event.buttons() == Qt.LeftButton:
            self.path.lineTo(event.pos())
            self.update()

    def mouseReleaseEvent(self, event):
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHints(painter.Antialiasing)

        painter.setPen(QPen(Qt.black, .5, Qt.SolidLine))

        painter.drawRect(self.rect())

        painter.drawPath(self.path)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM