super-class __init__() of type StartWindow was never called

Рейтинг: 1Ответов: 1Опубликовано: 23.03.2023

Есть два класса:

1 . Window()

class Window(QMainWindow): 
    def __init__(self):

        self.layout = QVBoxLayout()
        self.setGeometry(0, 0, 1200, 500)

        self.setWindowTitle('Basket Parse')
        
        # Введите дату
        self.dateLabel = QLabel(self)
        self.dateLabel.move(10, 10)
        self.dateLabel.setText('Введите дату')

        self.date = QLineEdit(self)
        self.date.move(10, 50)
        self.date.setInputMask('99.99')

        # Выберите браузер
        self.check = QComboBox(self)
        self.check.move(200, 30)
        self.check.addItems(["Google", "Firefox"])

        # Кнопка рассчитать 
        self.startButton = QPushButton(self)
        self.startButton.move(10, 100)
        self.startButton.setText('Рассчитать')

        self.saveButton = QPushButton(self)
        self.saveButton.move(120, 100)
        self.saveButton.setText('Сохранить в CSV')

        self.freqTable = QTableWidget(self)
        self.freqTable.setGeometry(700, 150, 480, 320) 
        self.freqTable.setColumnCount(5) 

        self.freqHeader = self.freqTable.horizontalHeader()    
        self.freqHeader.setSectionResizeMode(0, QHeaderView.Stretch)

        self.table = QTableWidget(self)
        self.table.setGeometry(10, 150, 680, 320) 
        self.table.setColumnCount(7)  
        
        # Настройка ширины ячеек
        self.header = self.table.horizontalHeader()    
        self.header.setSectionResizeMode(1, QHeaderView.Stretch)
        self.header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(5, QHeaderView.ResizeToContents)

        self.startButton.clicked.connect(self.startProgram)
        self.saveButton.clicked.connect(self.saveInFile)

        # Добавление элементов в шаблон 
        self.layout.addWidget(self.date)
        self.layout.addWidget(self.dateLabel)
        self.layout.addWidget(self.startButton)
        self.layout.addWidget(self.table)
        self.layout.addWidget(self.check)
        self.setLayout(self.layout)

2 . StartWindow()

class StartWindow(Window): 
   
    def __init__(self):
        super().__init__()

Также есть следующий код, который запускает приложение

def startApp(): 
    app = QApplication([])
    # Исп. как контейнер 
    window = StartWindow()
    window.show()
    app.exec_()

if __name__ == '__main__':
    startApp()

StartWindow наследник Window. Я хотел сделать так, чтобы при вызове StartWindow вызывался __init__() родителя. Для этого я использую функцию super(). Но у меня почему-то возникает следующая ошибка:

  window = StartWindow()
           ^^^^^^^^^^^^^
self.setGeometry(0, 0, 1200, 500)
RuntimeError: super-class __init__() of type StartWindow was never called

Не могу понять проблему. До этого в классе Window был super(), а у StartWindow __init__() не было вообще и всё работало

class Window(QMainWindow): 
    def __init__(self): 
        super(Window, self).__init__()

Я подумал, что будет правильнее перенести его в дочерний элемент, но столкнулся с этой проблемой. Подскажите, где ошибка?

Ответы

▲ 1Принят

Я не совсем понимаю что вы хотите сделать, но предложу вам вариант того , как это увидел я.

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


#class Window(QMainWindow): 
class Window(QWidget):                                        # !!! +++ QWidget
    def __init__(self):
        super().__init__()                                    # !!!
#?       self.setGeometry(0, 0, 1200, 500)
        self.resize(1200, 500)
        self.setWindowTitle('Basket Parse')
        
        # Введите дату
        self.dateLabel = QLabel('Введите дату')
#?       self.dateLabel.move(10, 10)
#        self.dateLabel.setText('Введите дату')

        self.date = QLineEdit()
        self.date.setMaximumWidth(94)
#?       self.date.move(10, 50)
        self.date.setInputMask('99.99')

        # Выберите браузер
        self.check = QComboBox()
#?       self.check.move(200, 30)
        self.check.addItems(["Google", "Firefox"])

        # Кнопка рассчитать 
        self.startButton = QPushButton('Рассчитать')
        self.startButton.clicked.connect(self.startProgram)        
#?       self.startButton.move(10, 100)
#        self.startButton.setText('Рассчитать')

        self.saveButton = QPushButton('Сохранить в CSV')
        self.saveButton.setMaximumWidth(94)
        self.saveButton.clicked.connect(self.saveInFile)        
#?       self.saveButton.move(120, 100)
#        self.saveButton.setText('Сохранить в CSV')

        self.freqTable = QTableWidget(15, 5)
#?       self.freqTable.setGeometry(700, 150, 480, 320) 
#        self.freqTable.setColumnCount(5) 

        self.freqHeader = self.freqTable.horizontalHeader()    
        self.freqHeader.setSectionResizeMode(0, QHeaderView.Stretch)

        self.table = QTableWidget(15, 7)
#?       self.table.setGeometry(10, 150, 680, 320) 
#        self.table.setColumnCount(7)  
        
        # Настройка ширины ячеек
        self.header = self.table.horizontalHeader()    
        self.header.setSectionResizeMode(1, QHeaderView.Stretch)
        self.header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        self.header.setSectionResizeMode(5, QHeaderView.ResizeToContents)

        # Добавление элементов в шаблон 
#        self.layout = QVBoxLayout(self)
# ------------------> vvvvvvvvvvv vvvv <-----------------------------------------
        self.layout = QGridLayout(self)                      # !!! +++ QGridLayout
        self.layout.addWidget(self.dateLabel, 0, 0, 1, 1)
        self.layout.addWidget(self.date, 1, 0, 1, 1)
        self.layout.addWidget(self.check, 0, 1, 2, 1)
        self.layout.addWidget(self.startButton, 2, 0)
        self.layout.addWidget(self.saveButton, 2, 1)
        self.layout.addWidget(self.table, 3, 0, 1, 5)
        self.layout.addWidget(self.freqTable, 3, 5, 1, 5)
    
#        self.setLayout(self.layout)

    def startProgram(self):
        print(f'def startProgram(self): ') 
        
    def saveInFile(self):
        print(f'def saveInFile(self): ') 
  
  
#class StartWindow(Window): 
class StartWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.centralwidget = QtWidgets.QWidget()           # !!! +++ centralwidget
        self.setCentralWidget(self.centralwidget)          # !!! +++ centralwidget

        self.window = Window()                                    # !!! +++

        layout = QtWidgets.QVBoxLayout(self.centralwidget)
        layout.addWidget(self.window)
        
 
def main(): 
    app = QApplication(sys.argv)
    # Исп. как контейнер 
    w = StartWindow()
    w.resize(1200, 500)
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main() 

введите сюда описание изображения



UPDATE:

Я немного почитал документацию к методу resize, но не совсем понимаю. Когда его использовать, а когда метод setGeometry.

И как вы определяете расположение элементов на экране? Аргументы к методу addWidget?

Когда его использовать resize() или setGeometry() - решать вам. Особой разницы нету.
Я просто привык что главное окно располагается в центре экрана, а не смещено куда-то. И это не есть ваша проблема.

Вам нада изучить Qt Main Window Framework
...
Примечание. Создание главного окна без центрального виджета не поддерживается. У вас должен быть центральный виджет, даже если это просто заполнитель.
И понимать различия использования QWidget и QMainWindow для вашего главного окна.

Научитесь использовать менеджеры компоновки: Layout Management

Все подробности о класс QGridLayout, который размещает виджеты в сетке, найдете по ссылке.