如何在Qt中的小部件上绘制形状

时间:2018-04-19 11:57:00

标签: python qt pyqt pyqt5

我试图在窗口小部件上绘制一个形状,根据我的理解,您可以通过覆盖action_button.clicked方法来完成此操作。但是,当我这样做时,形状在后面呈现。如何在前面渲染形状? 我使用的是pyqt5,我的测试代码是:

self.ui.action_btn

enter image description here

2 个答案:

答案 0 :(得分:2)

Qt小部件是从父级到子级的。 这意味着MyWidgetpaintEvent()绘制自己之前绘制自己(通过调用QPushButton)。

一种可能的解决方案是创建一个小部件来绘制矩形并使其成为QPushButton的兄弟(即MyWidget的孩子)。然后,您可以使用QPushButtonRectangleWidgetQWidget::stackUnder()来确定QWidget::raise()QWidget::lower()的呈现顺序。

答案 1 :(得分:1)

这本质上是一个常见问题的Python版本:如何在小部件上叠加内容。我有一系列与叠加相关的答案:firstsecondthird

第三个答案,用Python重新编写:

# https://github.com/KubaO/stackoverflown/tree/master/questions/python-overlay-49920532
from PyQt5 import Qt
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys

class Overlay(QWidget):
    def __init__(self, parent = None):
        QWidget.__init__(self, parent)
        self.setAttribute(Qt.WA_NoSystemBackground)
        self.setAttribute(Qt.WA_TransparentForMouseEvents)

    def paintEvent(self, event) {
        QPainter(self).fillrect(self.rect(), QColor(80, 80, 255, 128))

class Filter(QObject):
    def __init__(self, parent = None):
        QObject.__init__(self, parent)
        self.m_overlay = None
        self.m_overlayOn = None

    def eventFilter(self, w, event):
        if w.isWidgetType():
            if event.type() == QEvent.MouseButtonPress:
                if not m_overlay:
                    m_overlay = Overlay(w.parentWidget());
                    m_overlay.setGeometry(w.geometry());
                    m_overlayOn = w;
                    m_overlay.show();
            elif event.type() == QEvent.Resize:
                if m_overlay and m_overlayOn is w:
                    m_overlay.setGeometry(w.geometry());
        return False

if __name__ == "__main__":
    app = QApplication(sys.argv)
    filter = Filter()
    window = QWidget()
    layout = QHBoxLayout(window);
    for text in ["Foo", "Bar", "Baz"]:
        label = QLabel(text)
        label.installEventFilter(filter)
        layout.addWidget(label)
    window.setMinimumSize(300, 250)
    window.show()
    app.exec_()