Search code examples
pythonpyqtpyqt4qwidgetqcombobox

Getting a comboBox to set the shown widget?


I'm making a GUI for a python program I've written and would like to have an area show a different widget depending on the choice of a comboBox.

This is a MWE:

Main window I want the outlined area in this Main Window to show either the TextWidget or the CalendarWidget, depending on if the comboBox is set to Option 1 or Option 2

Text Widget Calendar Widget

All the GUIs are built using Qt Designer and a python file uses uic to load them.

import sys
from PyQt4 import QtCore, QtGui, uic

Main = "Main.ui"
MainUI, MainBase = uic.loadUiType(Main)
Text = "textwidget.ui"
TWidget, TBase = uic.loadUiType(Text)
Cal = "calendarwidget.ui"
CWidget, CBase = uic.loadUiType(Cal)

class OperatorGUI(MainBase, MainUI):
    def __init__(self, parent=None):
        super(OperatorGUI, self).__init__(parent)
        self.setupUi(self)
        self.comboBox.activated[str].connect(self.choose_widget)


    def choose_widget(self, choice):
        # Set the widget accorging to the choice
        #if choice == "Option 1":
        print choice


class TextWidget(TBase, TWidget):
    def __init__(self):
        # Something
        print "Text"

class CalendarWidget(CBase, CWidget):
    def __init__(self):
        # Something
        print "Calendar"


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = OperatorGUI()
    window.show()
    sys.exit(app.exec_())

If I use a QtDockWidget I can not place it where I want. I do not want it to be detachable or pop up in a separate window.

How can I solve this?

Edit

After some help from @eyllanesc the code now looks like this:

import sys
from PyQt4 import QtCore, QtGui, uic

Main = "Main.ui"
MainUI, MainBase = uic.loadUiType(Main)
Text = "textwidget.ui"
TWidget, TBase = uic.loadUiType(Text)
Cal = "calendarwidget.ui"
CWidget, CBase = uic.loadUiType(Cal)

class OperatorGUI(MainBase, MainUI):
    def __init__(self, parent=None):
        super(OperatorGUI, self).__init__(parent)
        self.setupUi(self)
        self.comboBox.activated[str].connect(self.choose_widget)

        self.ChangingWidget.setLayout(QtGui.QVBoxLayout())
        self.stacked = QtGui.QStackedWidget()
        self.ChangingWidget.layout().addWidget(self.stacked)
        self.textWidget = TextWidget()
        self.calendarWidget = CalendarWidget()
        self.stacked.addWidget(self.textWidget)
        self.stacked.addWidget(self.calendarWidget)


    def choose_widget(self, choice):
        # Set the widget accorging to the choice
        if choice == "Option 1":
            self.stacked.setCurrentWidget(self.textWidget)
        elif choice == "Option 2":
            self.stacked.setCurrentWidget(self.calendarWidget)
        print choice
        self.setupUi(self)
        self.show()


class TextWidget(TBase, TWidget):
    def __init__(self, parent=None):
        super(TextWidget, self).__init__(parent)
        self.setParent(parent)
        print "Text"

class CalendarWidget(CBase, CWidget):
    def __init__(self, parent=None):
        super(CalendarWidget, self).__init__(parent)
        self.setParent(parent)
        print "Calendar"


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = OperatorGUI()
    window.show()
    sys.exit(app.exec_())

Solution

  • To do this task it is recommended to use QStackedWidget, for this I assumed that the widget associated with that area can be accessed through self.widget:

    class OperatorGUI(MainBase, MainUI):
        def __init__(self, parent=None):
            super(OperatorGUI, self).__init__(parent)
            self.setupUi(self)
            self.comboBox.activated[str].connect(self.choose_widget)
    
            self.widget.setLayout(QVBoxLayout())
            self.stacked = QtGui.QStackedWidget()
            self.widget.layout().addWidget(self.stacked)
            self.textWidget = TextWidget()
            self.calendarWidget = CalendarWidget()
            self.stacked.addWidget(self.textWidget)
            self.stacked.addWidget(self.calendarWidget)
    
        def choose_widget(self, choice):
            # Set the widget accorging to the choice
            if choice == "Option 1":
                self.stacked.setCurrentWidget(self.textWidget)
            elif choice == "Option 2":
                self.stacked.setCurrentWidget(self.calendarWidget)