Sherafati
Sherafati

Reputation: 216

MRO error in PyQt5 when using multiple inheritance

I'm new to PyQt5. I'm trying to create a single window with a menuBar (which inherits from the QMainWindow class) and some other widgets such as a button, some labels and text editors (which require the QWidget class). This is my code. When i try to add QMainWindow and QWidget as parent classes to may mainwindow class, i get an error saying: "TypeError: Cannot create a consistent method resolution order (MRO) for bases QWidget, QMainWindow". when i use only 1 parent class for mainwindow class it works fine, but in this case i have to use both QMainWindow and QWidget as parent classes.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QAction, QMenu, QMainWindow, QTextEdit, QLineEdit, QGridLayout, QLabel

class mainwindow(QWidget, QMainWindow):
    def __init__(self):
        super().__init__()

        self.createUI()
    def createUI(self):
        mymenubar = self.menuBar()
        filemenu = mymenubar.addMenu("File")
        filemenu.addAction("help")
        filemenu.addAction("exit")



        contactlabel = QLabel("Contact:", self)
        contacttextedit = QLineEdit(self)
        countlabel = QLabel("Count:")
        counttextedit = QLineEdit()
        msglabel = QLabel("Your message here:")
        msgbox = QTextEdit()

        grid = QGridLayout()
        grid.setSpacing(10)




        grid.addWidget(contactlabel,1,0)
        grid.addWidget(contacttextedit,1,1)

        grid.addWidget(countlabel,2,0)
        grid.addWidget(counttextedit,2,1)

        grid.addWidget(msglabel,3,0)
        grid.addWidget(msgbox,3,1,5,1)

        self.setLayout(grid)
        self.setGeometry(300,300,300,300)
        self.setWindowTitle("Whatsapp Message Sender")
        self.show()



    # MODIFYING CLOSE EVENT SO IT ASKS BEFORE EXIT
    def closeEvent(self, event):
        reply = QMessageBox.question(self, "Message", "quit?", QMessageBox.Yes| QMessageBox.No, QMessageBox.Yes)

        if reply == QMessageBox.No:
            event.ignore()
        else:
            event.accept()



app = QApplication(sys.argv)
ex = mainwindow()
sys.exit(app.exec_())

What am i doing wrong? how can i use both QWidget and QMainwindow in my class?

Upvotes: 1

Views: 230

Answers (2)

eyllanesc
eyllanesc

Reputation: 243965

You have 2 errors:

  • QMainWindow already inherits from QWidget so multiple inheritance is unnecessary causing the error.

  • You should not establish a layout to a QMainWindow since it already has a predefined structure, instead you must create a central container where the layout is.

Considering the above, the solution is:

import sys
from PyQt5.QtWidgets import (
    QApplication,
    QWidget,
    QPushButton,
    QMessageBox,
    QAction,
    QMenu,
    QMainWindow,
    QTextEdit,
    QLineEdit,
    QGridLayout,
    QLabel,
)


class mainwindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.createUI()

    def createUI(self):
        mymenubar = self.menuBar()
        filemenu = mymenubar.addMenu("File")
        filemenu.addAction("help")
        filemenu.addAction("exit")

        contactlabel = QLabel("Contact:", self)
        contacttextedit = QLineEdit(self)
        countlabel = QLabel("Count:")
        counttextedit = QLineEdit()
        msglabel = QLabel("Your message here:")
        msgbox = QTextEdit()

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(contactlabel, 1, 0)
        grid.addWidget(contacttextedit, 1, 1)

        grid.addWidget(countlabel, 2, 0)
        grid.addWidget(counttextedit, 2, 1)

        grid.addWidget(msglabel, 3, 0)
        grid.addWidget(msgbox, 3, 1, 5, 1)

        # self.setLayout(grid)
        central_widget = QWidget()
        central_widget.setLayout(grid)
        self.setCentralWidget(central_widget)
        self.setGeometry(300, 300, 300, 300)
        self.setWindowTitle("Whatsapp Message Sender")
        self.show()

    # MODIFYING CLOSE EVENT SO IT ASKS BEFORE EXIT
    def closeEvent(self, event):
        reply = QMessageBox.question(
            self, "Message", "quit?", QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes
        )

        if reply == QMessageBox.No:
            event.ignore()
        else:
            event.accept()


if __name__ == "__main__":

    app = QApplication(sys.argv)
    ex = mainwindow()
    sys.exit(app.exec_())

Upvotes: 2

rbaleksandar
rbaleksandar

Reputation: 9691

I think the problem comes from the fact that QMainWindow also inherits from QWidget. That said there is no point in inheriting from QWidget if you are inheriting from QMainWindow. If you want to drop the special functionality QMainWindow offers, just drop it and use just plain QWidget instead.

Upvotes: 0

Related Questions