【问题标题】:QFrame is not taking QWidget as parent?QFrame 没有将 QWidget 作为父级?
【发布时间】:2019-02-08 02:37:33
【问题描述】:

我在这里尝试的是使 CancelCross 成为 Notifier 类的子级,但是当我这样做时,CancelCross 的十字是不可见的。但是,如果我取消它的父母,那么它可以很好地看到。我也尝试使用 QMainWindow 来养育它,但没有运气。我的代码有问题吗?

class CloseCrosss(QtGui.QFrame):
    def __init__(self, QWidgetparent = None):
        QtGui.QFrame.__init__(self, parent=QWidgetparent)


    def paintEvent(self, e):
        qp = QtGui.QPainter()
        pen = QtGui.QPen(Qt.red)
        qp.begin(self)
        qp.setPen(pen)
        qp.drawLine(460, 10, 470, 20)
        qp.drawLine(470, 10, 460, 20)
        qp.end()


class Notifier(QtGui.QWidget):
    def __init__(self, message=None):
        QtGui.QWidget.__init__(self)
        self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
        _desktop = QtGui.QApplication.desktop()
        size = _desktop.screenGeometry()

        self.resize(size.width() * 25 / 100, size.height() * 3 / 100)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.main_layout = QtGui.QVBoxLayout()
        self.move(size.width() - (size.width() * 25 / 100) - 10, 50)

        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)

        self.label = QtGui.QLabel(message)
        self.label.setStyleSheet("color: lightgreen; font: 14px;")
        self.label.setIndent(20)
        self.main_layout.addWidget(self.label)
        self.setLayout(self.main_layout)


    def paintEvent(self, event):
        s = self.size()
        qp = QtGui.QPainter()
        qp.begin(self)
        qp.setRenderHint(QtGui.QPainter.Antialiasing, True)
        qp.setPen(QtGui.QColor(255, 255, 255, 200))
        qp.setBrush(QtGui.QColor(0, 0, 0, 200))
        qp.drawRoundedRect(0, 0, s.width(), s.height(), 5, 5)
        qp.end()


    def closeEvent(self):
        self.kill()


if __name__ == "__main__":
    QApp = QtGui.QApplication(sys.argv)
    window = Notifier()
    cross = CloseCrosss(QWidgetparent=window)
    window.show()
    cross.show()
    QApp.exec_()

【问题讨论】:

  • 为什么是10+450, 10, 20+450, 20
  • @eyllanesc 哦,我只是在玩一些价值观,一旦我得到完美的价值观,我会把它改成那样。

标签: python pyqt pyqt4 qwidget qframe


【解决方案1】:

孩子的位置是相对于他们的父母,如果一个小部件没有父亲,那么它的位置是相对于屏幕的。并且该坐标系用于绘制,例如在您的情况下,qp.drawLine(460, 10, 470, 20) 表示您将从(460, 10)(470, 20) 的线绘制到通知程序。 Notifier 的高度是屏幕的 3%,而对于我的 3% 的屏幕,它比 470 小很多,所以这幅画被丢弃了。

在你的情况下,我知道你想画一个 10x10 的十字,然后只画那个十字,然后把它移到左上角。

import sys
from PyQt4 import QtCore, QtGui


class CloseCrosss(QtGui.QFrame):
    clicked = QtCore.pyqtSignal()

    def __init__(self, side=10, parent=None):
        QtGui.QFrame.__init__(self, parent)
        self._side = side
        self.setFixedSize(side, side)
        if parent:
            parent.installEventFilter(self)

    def mouseReleaseEvent(self, event):
        self.clicked.emit()
        QtGui.QFrame.mouseReleaseEvent(self, event)

    def paintEvent(self, e):
        qp = QtGui.QPainter(self)
        qp.setPen(QtCore.Qt.red)
        qp.drawLine(0, 0, self._side, self._side)
        qp.drawLine(self._side, 0, 0, self._side)

    def eventFilter(self, watched, event):
        if watched == self.parentWidget() and self.parentWidget():
            if event.type() == QtCore.QEvent.Resize:
                self.adjustSize()
        return QtGui.QFrame.eventFilter(self, watched, event)

    def adjustSize(self):
        # move widget to topright
        self.move(self.parentWidget().width() -self.width()-5, 5)


class Notifier(QtGui.QWidget):
    def __init__(self, message=None):
        QtGui.QWidget.__init__(self, flags=QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint)
        _desktop = QtGui.QApplication.desktop()
        size = _desktop.screenGeometry().size()

        self.resize(size.width() * 25 / 100, size.height() * 3 / 100)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.main_layout = QtGui.QVBoxLayout(self)
        self.move(size.width() - (size.width() * 25 / 100) - 10, 50)

        self.main_layout.setContentsMargins(0, 0, 0, 0)
        self.main_layout.setSpacing(0)

        self.label = QtGui.QLabel(message)
        self.label.setStyleSheet("color: lightgreen; font: 14px;")
        self.label.setIndent(20)
        self.main_layout.addWidget(self.label)
        cross = CloseCrosss(parent=self)
        cross.clicked.connect(self.close)


    def paintEvent(self, event):
        qp = QtGui.QPainter(self)
        qp.setRenderHint(QtGui.QPainter.Antialiasing, True)
        qp.setPen(QtGui.QColor(255, 255, 255, 200))
        qp.setBrush(QtGui.QColor(0, 0, 0, 200))
        qp.drawRoundedRect(QtCore.QRect(QtCore.QPoint(), self.size()), 5, 5)


if __name__ == "__main__":
    QApp = QtGui.QApplication(sys.argv)
    window = Notifier("Hello World")
    window.show()
    sys.exit(QApp.exec_())

【讨论】:

  • 谢谢我现在明白了这个问题。你的回答也是正确的,但我找到了一条捷径。所以我只是添加了``if QWidgetparent: size = self.parent().size() self.resize(size)
  • @laslavinco 如果我的回答对你有帮助,别忘了标记为正确,如果你不知道怎么做,请查看tour,这是最好的感谢方式。
  • @laslavinco 您的解决方案与我的相同,但是如果您更改窗口的大小会产生问题,但我的解决方案会自动更正。
  • 是的,我完全忘记了这一点。感谢您的帮助:)
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-19
  • 2020-06-23
相关资源
最近更新 更多