To the point: I have several panels that I would like to access via a bar. In order to make things easier, I want to loop through the module and auto-populate my main window with the relevant panels. This is my first stab at GUI / PyQT5, so please let me know if there is a better way of doing this!
My issue is that when a triggered action occurs (clicking on the dropdown menu for FirstPanel for instance), the name that is pulled in showPanel is qt_set_sequence_auto_mnemonic, which seems to be the last name in inspect. I guess the openPanel connection isn't preserved somehow, or maybe it is impossible to loop through. I don't have a great understanding of how the triggered actions occur, but any advice would be welcome.
Here are my panels in the "panel" module:
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class FirstPanel(QDialog):
"""
First Panel.
"""
def __init__(self, parent = None):
super(FirstPanel, self).__init__(parent)
layout = QVBoxLayout()
self.name = "The first panel"
self.label = QLabel(self.name)
layout.addWidget(self.label)
self.setLayout(layout)
self.initUI()
def initUI(self):
"""
Initialize UI for Panel
"""
self.setGeometry(300,300,300,220)
self.setWindowTitle(self.name)
class SecondPanel(QDialog):
"""
Second panel...
"""
Now, my main window will grab the relevant panels from this list and populate the drop bar:
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QIcon
import inspect
import panels
class Main_Window(QMainWindow):
def __init__(self, parent = None):
"""
Constructor for the Main_Window GUI. Inherits from QMainWindow.
All other windows should be children.
"""
super(Main_Window, self).__init__(parent)
self.initUI()
def initUI(self):
"""
Initializes menu and initial panels.
"""
self.initMenuBar()
# Create window...
self.setGeometry(300, 300, 300, 200)
self.setWindowIcon(QIcon(''))
self.setWindowTitle('Control Panels')
self.show()
def initMenuBar(self):
"""
Initializes the main menu bar so that the user can safely
open closed / unopened panels. As long as panel is defined
in panels, it will be populated here!
TO DO: Add more usability
"""
self.statusBar()
menubar = self.menuBar()
panelMenu = menubar.addMenu('&Panels')
# Add actions to the panel menu
# Let's do an intuitive approach...
# This will parse panels for available panels
for name, obj in inspect.getmembers(panels):
if str(obj).find('panels') != -1:
if str(name).find('Panel') != -1:
openPanel = QAction(QIcon(), name, self)
openPanel.triggered.connect(lambda : self.showPanel(str(name)))
panelMenu.addAction(openPanel)
### MORE MENU ITEMS ###
return menubar
""" Show Window Functions """
def showPanel(self,panelString):
"""
PyQT5 likes calling windows from external functions when connecting.
"""
print(panelString)
win = getattr(panels, panelString)(self)
win.show()
def main():
app = QApplication(sys.argv)
ex = Main_Window()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Finally, when I run the GUI and try to click on a panel in the drop bar this is the error:
qt_set_sequence_auto_mnemonic
Traceback (most recent call last):
File "experiment_panel.py", line 59, in <lambda>
openPanel.triggered.connect(lambda : self.showPanel(str(name)))
File "experiment_panel.py", line 70, in showPanel
win = getattr(panels, panelString)(self)
TypeError: qt_set_sequence_auto_mnemonic(bool): argument 1 has unexpected type 'Main_Window'