PyQt5:QPainter覆盖QWidget

时间:2017-12-29 12:41:06

标签: python pyqt pyqt4 pyqt5

对于这个问题,我指的是@Kuba Ober Draw Rectangular overlay on QWidget at click

的回答

我的问题:我不知道如何"翻译"将C ++(或C?)转换为Python。 : - (

因此我问这个"重复"再次提问,并希望任何人都能帮助重写代码以在PyQt5中实现叠加效果。

作为一个例子,我在这里准备了一些代码:

# -*- coding: utf-8 -*-

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

class MyApp(QWidget):
    def __init__(self):
        super(MyApp, self).__init__()
        self.initUI()

    def initUI(self):
        self.text = "hello world"
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle('Draw Demo')

        self.btn = QPushButton("Butten should be overlayed", self)
        self.btn.setFixedSize(200, 200)
        self.btn.move(40, 40)

        self.show()

    def paintEvent(self, event):
        qp = QPainter()
        qp.begin(self)
        qp.setPen(QColor(Qt.red))
        qp.setFont(QFont('Arial', 20))

        qp.drawText(10, 50, "hello Python")
        qp.setPen(QColor(Qt.blue))
        qp.drawLine(10, 100, 100, 100)
        qp.drawRect(10, 150, 150, 100)

        qp.setPen(QColor(Qt.red))
        qp.drawEllipse(100, 50, 100, 50)
#        qp.drawPixmap(220, 10, QPixmap("python.jpg"))
        qp.fillRect(200, 175, 150, 100, QBrush(Qt.SolidPattern))
        qp.end()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())

目标是:让按钮显示在背景中(由QPainter覆盖),但它对鼠标事件是透明的。因此我可以点击按钮,即使它被QPainter覆盖。

任何帮助都将受到高度赞赏!

1 个答案:

答案 0 :(得分:1)

如果我们知道两种语言之间的等价和差异,从C ++到Python的翻译很简单,如下所示:

<强> overLay.py

import sys

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


class OverLay(QWidget):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)
        self.setAttribute(Qt.WA_NoSystemBackground)
        self.setAttribute(Qt.WA_TransparentForMouseEvents)

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), QColor(80, 80, 255, 128))

class Filter(QObject):
    def __init__(self, *args, **kwargs):
        QObject.__init__(self, *args, **kwargs)
        self.m_overlay = None
        self.m_overlayOn = None

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


if __name__ == '__main__':
    app = QApplication(sys.argv)
    filt = Filter()
    window = QWidget()
    lay = QHBoxLayout(window)
    for text in ( "Foo", "Bar", "Baz "):
        label = QLabel(text)
        lay.addWidget(label)
        label.installEventFilter(filt)
    window.setMinimumSize(300, 250)
    window.show()
    sys.exit(app.exec_())

了解您要在窗口小部件中执行的操作,您必须使用以下代码:

<强> main.py

# -*- coding: utf-8 -*-

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

from overlay import Filter


class MyApp(QWidget):
    def __init__(self):
        super(MyApp, self).__init__()
        self.initUI()

    def initUI(self):
        self.text = "hello world"
        self.setGeometry(100, 100, 400, 300)
        self.setWindowTitle('Draw Demo')

        self.btn = QPushButton("Butten should be overlayed", self)
        self.btn.setFixedSize(200, 200)
        self.btn.move(40, 40)
        filt = Filter(self)
        self.btn.installEventFilter(filt)

        self.show()

    [...]

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec_())