Как правильно переопределить showEvent для QWidget или QMainWindow? Должен ли супер всегда называться, и если да, то как? - PullRequest
1 голос
/ 15 января 2020

Используя PyQt5, я использую QWidget в качестве основной формы (также может быть QMainWindow).

Мне нужно что-то сделать после того, как Qt определит размер основной формы в зависимости от размера экрана и других факторов, поэтому я не могу использовать конструктор, скорее, я должен переопределить showEvent. Пример того, почему это необходимо в некоторых случаях или более подробно, см., Например, в этом посте: Получение размера 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(MainForm, self).showEvent(event) или super().showEvent(event)? Я не могу найти ситуацию, когда один работает, а другой нет, и я нашел несколько примеров использования каждого способа. Есть ли существенная разница между ними?

  3. Если нужно вызвать super, следует ли выполнять другие функции (например, установка изображения QGraphicsView) до или после вызова super? Имеет ли это значение, и если да, то какие практические различия могут вызывать другие действия перед vs после вызова super?

1 Ответ

2 голосов
/ 15 января 2020

1. Имеет ли значение, если супер называется? В моем ограниченном тестировании я не могу найти, что это имеет значение для этой функции.

Это зависит от того, когда вы вызываете 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 (MainForm, self) .showEvent (событие) или super (). ShowEvent (событие)? Я не могу найти ситуацию, когда один работает, а другой нет, и я нашел несколько примеров использования каждого способа. Есть ли существенная разница между ними?

На этот вопрос дан ответ в Понимание Python super () с помощью методов __init __ () , оба эквивалентны в python3.

3. Если нужно вызвать super, следует ли выполнять другие функции (например, устанавливать изображение QGraphicsView) до или после вызова super? Имеет ли это значение, и если да, то каковы практические различия, которые могут вызывать другие действия перед vs после вызова super?

Это зависит. Это будет зависеть от понимания того, что делает родительский метод, например, если вы хотите, чтобы ваши дополнительные функции выполнялись до или после поведения по умолчанию.


В вашем конкретном случае, так как вы переопределяете метод showEvent в MainForm который наследует непосредственно от QWidget, который ничего не делает согласно исходному коду , не имеет значения, если вы вызываете метод showEvent (хотя рекомендуется вызывать super () в качестве хорошей практики), это также не имеет значения что вы добавляете функциональность до или после супер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...