Подкласс Абстрактный Класс

#python #pyqt #pyqt5

#python #pyqt #pyqt5

Вопрос:

Мне нужно перехватить действия по увеличению и уменьшению кнопок spinbox, чтобы запустить некоторый код для запуска. Тем не менее, я считаю, что мне нужно создать подкласс абстрактного класса, но я не совсем уверен, как это сделать правильно.

Я еще не пробовал его кодировать, но не смог найти ни одного хорошего примера с помощью Google. Я считаю, что имею правильное направление в spinbox.py файл, но не уверен, что именно мне нужно сделать.

spinboxui.py

 from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(200, 150)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.spinBox = QtWidgets.QSpinBox(self.groupBox)
        self.spinBox.setObjectName("spinBox")
        self.gridLayout_2.addWidget(self.spinBox, 0, 0, 1, 1)
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setText("")
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
 

spinbox.py

 import sys
from spinboxui import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets

class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.setupUi(self)

    def do_something(self):
        pass


class QAbstractSpinBox(QtWidgets.QAbstractSpinBox):

    def __init__(self):
        QAbstractSpinBox.__init__(self)

    def stepUp(self):
        pass


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    spinbox = Main()
    spinbox.show()
    sys.exit(app.exec_())
 

Я хотел бы перехватить команду step up, выполнить немного кода, а затем разрешить выполнение spinbox. Я использую spinbox в качестве перелистывателя страниц для обычного текстового поля редактирования, поскольку поле spin увеличивается или уменьшается, оно изменяет «страницу» в обычном текстовом редакторе. У меня есть код, который должен выполняться на странице, на которой он был последним, прежде чем перейти к следующей «странице».

Комментарии:

1. Почему бы просто не использовать его valueChanged сигнал?

2. Я пытался. Но это запускает функцию слишком поздно. Например, я нахожусь на «странице 1», так как я собираюсь перейти на «страницу 2», функция срабатывает и влияет только на «страницу 2», а не на предыдущую страницу. Мне нужна эта функция для запуска пошаговых взлетов и падений.

3. Да, опечатка, но не влияет на обработку триггеров. Я исправлю опечатку.

4. Вы имеете в виду, что хотите, чтобы spinbox поднимался и опускался по Abstractclass вместо valueChanged signal ?

5. Итак, QAbstractSpinBox имеет триггерные слоты для StepUp и stepDown. Согласно вики, повышение на один линейный шаг, вызывающий этот слот, аналогично вызову stepBy (1); . Если я правильно читаю, это слот, который фактически увеличивает spinbox на одну цифру. Что мне нужно сделать, так это перехватить stepup. Например, вы можете щелкнуть стрелку вверх, чтобы увеличить значение. Когда пользователь нажимает кнопку, мне нужна функция для запуска, как только функция завершится, она увеличит значение.

Ответ №1:

Вам не нужно:

  • Наследовать от QAbstractSpinBox, потому что создание класса с тем же именем, от которого наследуется QSpinBox, не изменит его поведение
  • Перезапишите stepUp() метод, поскольку этот метод вызывает stepBy() метод только разработчиком, вместо этого вы должны перезаписать stepBy() метод и убедиться, что шаги являются положительными или 1, как вы хотите.

spinbox.py

 from PyQt5 import QtWidgets


class SpinBox(QtWidgets.QSpinBox):
    def stepBy(self, steps):
        if steps > 0:
            print("execute function")
        super(SpinBox, self).stepBy(steps)
 

spinboxui.py

 from PyQt5 import QtCore, QtGui, QtWidgets

from spinbox import SpinBox


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(200, 150)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
        self.groupBox.setObjectName("groupBox")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.spinBox = SpinBox(self.groupBox)
        self.spinBox.setObjectName("spinBox")
        self.gridLayout_2.addWidget(self.spinBox, 0, 0, 1, 1)
        self.label = QtWidgets.QLabel(self.groupBox)
        self.label.setText("")
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 0, 1, 1, 1)
        self.gridLayout.addWidget(self.groupBox, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
 

main.py

 import sys
from spinboxui import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets


class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.setupUi(self)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    spinbox = Main()
    spinbox.show()
    sys.exit(app.exec_())
 

Если вы хотите выполнить функцию в main.py , лучше всего создать сигнал:

spinbox.py

 from PyQt5 import QtCore, QtWidgets


class SpinBox(QtWidgets.QSpinBox):
    upSignal = QtCore.pyqtSignal()

    def stepBy(self, steps):
        if steps > 0:
            self.upSignal.emit()
        super(SpinBox, self).stepBy(steps)
 

main.py

 import sys
from spinboxui import Ui_MainWindow
from PyQt5 import QtCore, QtGui, QtWidgets


class Main(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super().__init__()
        self.setupUi(self)
        self.spinBox.upSignal.connect(self.on_up)

    @QtCore.pyqtSlot()
    def on_up(self):
        print("up")


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    spinbox = Main()
    spinbox.show()
    sys.exit(app.exec_())