Search code examples
pythonpyqt5qmainwindowqmenubarqstatusbar

PyQt5: main window shows without any widgets


I'm using PyQt5 to create my application. The problem is that my window appears, but without any widgets (i.e. without my Main class, without any menus, toolbars, etc.) - just still empty. I'm using Python-3.6 and PyQt5, Windows 10 environment.

Here's my code:

app.py:

#!/usr/bin/env python
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, qApp, QWidget, QMainWindow, QGridLayout, QMenuBar, QAction, QToolBar, QStatusBar

from views import Main
 
class TerraSoft(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.setWindowTitle('TerraSoft')
        self.setWindowState(Qt.WindowMaximized)

        # init menu
        menubar = QMenuBar()
        fileMenu = menubar.addMenu('File')

        #init toolbar
        exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.triggered.connect(qApp.quit)
        
        toolbar = QToolBar()

        # load ihm
        main = Main()
        centWidget = QWidget()

        # widget centralizer
        window = QGridLayout()
        window.addWidget(main, 0, 0)
        centWidget.setLayout(window)
        
        self.setCentralWidget(centWidget)

        #status bar
        statusBar = QStatusBar().showMessage('Bienvenue dans TerraSoft')
        
        # show ihm
        self.show()
        main.show()
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = TerraSoft()
    ex.show()
    sys.exit(app.exec_())

.views (main)

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QWidget, qApp, QAction, QSplitter, QMenuBar, QToolBar, QGridLayout, QStatusBar

from Family.views import FamilyTreeView
from Specie.views import EventsTableView

class Main(QWidget):
    """description of class"""
    def __init__(self, *args):
        QWidget.__init__(self, *args)

        # init elements of widget
        familyTreeView = FamilyTreeView(self)
        eventsTableView = EventsTableView(self)

        #init splitters
        HSplitter = QSplitter(Qt.Horizontal)
        VSplitter = QSplitter(Qt.Vertical)

        # add elements to splitters
        HSplitter.addWidget(familyTreeView)
        HSplitter.addWidget(eventsTableView)

        
        grid = QGridLayout()
        grid.addWidget(HSplitter)

My module family.views (I want to add .models in the future, but one thing after other):

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QWidget, QTreeView

families = [
    ("Craspedocephalus", [
        ("puniceus", []),
        ("trigonocephalus", [])
    ]),
    ("Trimeresurus", [
        ("albolabris", [])
    ]),
    ("Elapidé", [])
]

class FamilyTreeView(QWidget):
    """description of class"""
    def __init__(self, *args):
        QWidget.__init__(self, *args)
        
        self.familyList = QTreeView()
        self.familyList.setMaximumWidth(300)
        
        self.model = QStandardItemModel()
        self.addItems(self.model, families)
        self.familyList.setModel(self.model)
        
        self.model.setHorizontalHeaderLabels([self.tr("Familles")])

    def addItems(self, parent, elements):     
        for text, children in elements:
            item = QStandardItem(text)
            parent.appendRow(item)
            if children:
                self.addItems(item, children)

and my module specie.views:

import sys

from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QApplication, QWidget, QTableWidget, QTreeView

class EventsTableView(QTableWidget):
    """description of class"""
    def __init__(self, *args):
        QTableWidget.__init__(self, *args)

        self.eventsTable = QTableWidget()
        self.eventsTable.setColumnCount(3)
        self.eventsTable.setHorizontalHeaderLabels(('Date', 'Catégorie', 'Description'))

You can see the result below:

You can see the result bellow:


Solution

  • To fix your example, use this Main class:

    class Main(QWidget):
        def __init__(self, *args):
            QWidget.__init__(self, *args)
    
            familyTreeView = FamilyTreeView(self)
            eventsTableView = EventsTableView(self)
    
            HSplitter = QSplitter(Qt.Horizontal)
    
            HSplitter.addWidget(familyTreeView)
            HSplitter.addWidget(eventsTableView)
            HSplitter.setStretchFactor(1, 1)
    
            grid = QGridLayout()
            grid.addWidget(HSplitter)
            self.setLayout(grid)
    

    this TerraSoft class:

    class TerraSoft(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.setWindowTitle('TerraSoft')
            self.setWindowState(Qt.WindowMaximized)
    
            exitAct = QAction(QIcon('exit24.png'), 'Exit', self)
            exitAct.setShortcut('Ctrl+Q')
            exitAct.triggered.connect(qApp.quit)
    
            fileMenu = self.menuBar().addMenu('File')
            fileMenu.addAction(exitAct)
    
            toolbar = self.addToolBar('Main')
            toolbar.addAction(exitAct)
    
            main = Main()
            self.setCentralWidget(main)
    
            self.statusBar().showMessage('Bienvenue dans TerraSoft')
    

    this FamilyTreeView class:

    class FamilyTreeView(QTreeView):
        def __init__(self, *args):
            QTreeView.__init__(self, *args)
            self.setMaximumWidth(300)
            self.setModel(QStandardItemModel(self))
            self.model().setHorizontalHeaderLabels([self.tr("Familles")])
            self.addItems(self.model(), families)
    
        def addItems(self, parent, elements):
            for text, children in elements:
                item = QStandardItem(text)
                parent.appendRow(item)
                if children:
                    self.addItems(item, children)
    

    and this EventsTableView class:

    class EventsTableView(QTableWidget):
        def __init__(self, *args):
            QTableWidget.__init__(self, *args)
            self.setColumnCount(3)
            self.setHorizontalHeaderLabels(('Date', 'Catégorie', 'Description'))