python - 如何正确覆盖 QWidget 或 QMainWindow 的 showEvent ?是否应该始终调用 super?如果是,如何调用?

标签 python pyqt pyqt5

使用 PyQt5,我使用 QWidget 作为我的主窗体(也可以是 QMainWindow)。

我需要在Qt根据屏幕尺寸和其他因素决定主窗体的尺寸后做一些事情,因此我不能使用构造函数,而是必须重写showEvent。有关为什么在某些情况下这是必要的示例或更多详细信息,请参阅例如这篇文章:Getting the size of a QGraphicsView

这是一个快速的框架示例:

# test.py

import cv2
import numpy as np

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QGridLayout
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.Qt import Qt


def main():
    app = QApplication([])
    mainForm = MainForm()
    mainForm.show()
    app.exec()
# end main

class MainForm(QWidget):

    def __init__(self):
        super().__init__()

        self.setGeometry(300, 300, 400, 200)

        self.label = QLabel('hello world')
        self.label.setAlignment(Qt.AlignCenter)

        self.gridLayout = QGridLayout()
        self.gridLayout.addWidget(self.label)
        self.setLayout(self.gridLayout)
    # end function

    def showEvent(self, event):
        print('in showEvent')
        # Set image on QGraphicsView here, or something else that has to be done in showEvent

        # Which of these is correct ??
        super(MainForm, self).showEvent(event)
        super().showEvent(event)
    # end function
# end class

if __name__ == '__main__':
    main()

我关于如何正确重写 showEvent 的具体问题是:

  1. 是否调用 super 有关系吗?在我有限的测试中,我找不到它对这个功能有什么特别的影响。

  2. super 应该被称为 super(MainForm, self).showEvent(event)super().showEvent(event) 吗?我找不到一种有效而另一种无效的情况,并且我找到了每种方法的多个示例。它们之间有有意义的区别吗?

  3. 如果应该调用 super,其他功能(例如设置 QGraphicsView 的图像)应该在调用 super 之前还是之后完成?这重要吗?如果重要的话,在调用 super 之前和之后执行其他操作会导致什么实际差异?

最佳答案

<强>1。 super 被调用有什么关系吗?在我有限的测试中,我找不到它对这个功能有什么特别的影响。

这取决于,当您调用 super().method(args) 时,您正在调用父类的功能,如果父类在该方法中实现了某些功能,则在其他情况下不是为了开发商应该做什么决定,如果他这样做或不这样做。如果父类没有实现任何额外的功能,那么调用它或不调用它都会执行相同的操作,但如果它实现了一些其他功能并且您没有调用它,则该类可能无法正确完成其工作。

因此,一般来说,调用父级的 super().method(args) 方法被认为是很好的做法,除非您想覆盖该行为。

要了解如果不调用父级方法会发生什么,可以使用以下示例:

import sys

from PyQt5 import QtCore, QtWidgets


class LineEdit(QtWidgets.QLineEdit):
    def keyPressEvent(self, event):
        print(event.text())
        # super().keyPressEvent(event)


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    w = LineEdit()
    w.show()
    sys.exit(app.exec_())

在下面的示例中,为了不调用父级的 keyPressEvent 方法,您已禁用默认行为,以便文本不会显示在 QLineEdit 中。但是如果您对 QWidget 执行相同的操作,则不会有任何问题,因为该类的 keyPressEvent 方法没有实现任何内容。

<强>2。 super 应该被称为 super(MainForm, self).showEvent(event) 还是 super().showEvent(event) ?我找不到一种有效而另一种无效的情况,并且我找到了每种方法的多个示例。这些之间有有意义的区别吗?

此问题已在 Understanding Python super() with __init__() methods 中得到解答,两者在 python3 中是等效的。

<强>3。如果应该调用 super,其他功能(例如设置 QGraphicsView 的图像)应该在调用 super 之前还是之后完成?这重要吗?如果重要的话,在调用 super 之前和之后做其他事情会导致什么实际差异?

这要看情况。这取决于对父方法的作用的理解,例如,您是否希望额外的功能在默认行为之前或之后运行。


在您的特定情况下,因为您要重写直接从 QWidget 继承的 MainForm 的 showEvent 方法,所以根据 the source code 不执行任何操作。调用 showEvent 方法并不重要(尽管建议您调用 super() 作为良好实践),在 super 之前或之后添加功能也并不重要。

关于python - 如何正确覆盖 QWidget 或 QMainWindow 的 showEvent ?是否应该始终调用 super?如果是,如何调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59758523/

相关文章:

python - Spark 中使用 Lambda 进行列表转换

python - 错误:Can't assign to function call Python/PyQt

python - 单击确定后执行功能(QDialogBu​​ttonBox)

python - QThreadPool 按顺序运行而不是并行运行,是什么导致我的代码线程不并行运行?

python - 无法在pygame中将文本添加到屏幕

python - Py_buffer在2.x中的用途 "multi-dimensional array"是什么?

python - 将 python 模块添加到 Azure

python - 如何在PyQt5中捕获libpng错误错误的自适应滤波器

python - PyQt GUI 操作顺序

python - 如何禁用 PyQt5 中的右键单击和小部件问题