Search code examples
pythonpyqtqtguiqmainwindowqdialog

Change my Qdialog to QMainWindow


Building off of some random example I hacked out this beautiful window. I regret using a QDialog example rather than a QMainWindow. I like the look of the QMainWindow and its features. Now I cannot make the conversion (sheer ignorance). The code is getting rather long so I thought I'd call this code from a QMainWindow, but when i do there is some catastrophe that shuts all python down. Can I convert this to a QMainWindow or call this from a QMainWindow?

import sys
from PyQt4 import QtCore, QtGui
import numpy as np
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as    NavigationToolbar
import matplotlib.pyplot as plt
import matplotlib.image as mpimg



class Window(QtGui.QDialog):

    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.resize(900,600)

        layout = QtGui.QHBoxLayout(self)
        Right = QtGui.QVBoxLayout(self)
        Left = QtGui.QVBoxLayout(self)
        spacer = QtGui.QSpacerItem(20,40)
        spacer2 = QtGui.QSpacerItem(10,40)

        font = QtGui.QFont()
        font.setFamily("Rod")
        font.setPointSize(23)
        font2 = QtGui.QFont()
        font2.setFamily("Rod")
        font2.setPointSize(18)
        font3 = QtGui.QFont()
        font3.setFamily("Rod")
        font3.setPointSize(13)

        #Plotting Methods from Matplotlib
        self.figure = plt.figure()
        self.canvas = FigureCanvas(self.figure)
        self.canvas.setMaximumHeight(525)
        self.canvas.setMaximumHeight(725)
        self.toolbar = NavigationToolbar(self.canvas, self)


       #Labels
        self.label = QtGui.QLabel(self)
        self.label.setFont(font)
        self.label.setText("  Welcome to PPMS Data Analyser")
        self.label.setMaximumSize(625,30)

        label2 = QtGui.QLabel(self)
        label2.setFont(font2)
        label2.setText("Select Plot:")

        x_label = QtGui.QLabel(self)
        x_label.setFont(font3)
        x_label.setText("x axis:")

        y_label = QtGui.QLabel(self)
        y_label.setFont(font3)
        y_label.setText("y axis:")

        #Push Buttons
        fileSelect = QtGui.QPushButton('Select File')
        fileSelect.setMaximumSize(70,25)
        fileSelect.clicked.connect(self.plot)
        goPlot = QtGui.QPushButton('Plot')
        goPlot.setMaximumSize(60,20)
        goPlot.clicked.connect(self.plot)





        # x axis radio buttons
        groupBox = QtGui.QGroupBox()
        radio1 = QtGui.QRadioButton("Time")
        radio2 = QtGui.QRadioButton("Delta T")
        radio3 = QtGui.QRadioButton("Delta V")
        radioa = QtGui.QRadioButton("Hot Side Temp")
        radiob = QtGui.QRadioButton("Cold Side Temp")
        radioc = QtGui.QRadioButton("System Temp")
        radio2.setChecked(True)


        # Vertically aligns these buttons
        vbox = QtGui.QVBoxLayout()
        vbox.addWidget(x_label)
        vbox.addWidget(radio1)
        vbox.addWidget(radio2)
        vbox.addWidget(radio3)
        vbox.addWidget(radioa)
        vbox.addWidget(radiob)
        vbox.addWidget(radioc)
        vbox.addStretch(1)
        groupBox.setLayout(vbox)

        # y axis radio buttons
        groupBox2 = QtGui.QGroupBox()
        radio12 = QtGui.QRadioButton("Time")
        radio22 = QtGui.QRadioButton("Delta T")
        radio32 = QtGui.QRadioButton("Delta V")
        radioa2 = QtGui.QRadioButton("Hot Side Temp")
        radiob2 = QtGui.QRadioButton("Cold Side Temp")
        radioc2 = QtGui.QRadioButton("System Temp")
        radio32.setChecked(True)

        # Vertically aligns these buttons
        vbox2 = QtGui.QVBoxLayout()
        vbox2.addWidget(y_label)
        vbox2.addWidget(radio12)
        vbox2.addWidget(radio22)
        vbox2.addWidget(radio32)
        vbox2.addWidget(radioa2)
        vbox2.addWidget(radiob2)
        vbox2.addWidget(radioc2)
        vbox2.addStretch(1)
        groupBox2.setLayout(vbox2)

        #Box for 2 radio boxes
        hbox0 = QtGui.QHBoxLayout()
        hbox0.addWidget(groupBox)
        hbox0.addWidget(groupBox2)
        hbox0.addStretch(0)

        Left.addWidget(self.label)
        Left.addWidget(self.canvas)
        Left.addWidget(self.toolbar)
        Right.addItem(spacer)
        Right.addWidget(fileSelect)
        Right.addItem(spacer)
        Right.addWidget(label2)
        Right.addLayout(hbox0)
        Right.addWidget(goPlot)
        Right.addLayout(hbox0)

        layout.addLayout(Left)
        layout.addLayout(Right)


    def plot(self):
        ax = self.figure.add_subplot(111)
        ax.hold(False)
        ax.plot([1,2],[3,4])
        plt.grid()
        plt.title('Test Plot')
        self.canvas.draw()



if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    main = Window()
    main.setWindowTitle('PPMS Seebeck Calculator')
    main.show()

    sys.exit(app.exec_())

Solution

  • QMainWindow has a pre-set layout [docs]. First of all, you need to create a “central widget” for the QMainWindow, and add the your own layouts to that widget. This is the working code:

    import sys
    from PyQt4 import QtCore, QtGui
    import numpy as np
    from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
    from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as    NavigationToolbar
    import matplotlib.pyplot as plt
    import matplotlib.image as mpimg
    
    
    
    class Window(QtGui.QMainWindow):
    
        def __init__(self, parent=None):
            super(Window, self).__init__(parent)
            self.resize(900,600)
    
            self.central_widget = QtGui.QWidget()
            self.setCentralWidget(self.central_widget)
    
            layout = QtGui.QHBoxLayout()
            Right = QtGui.QVBoxLayout()
            Left = QtGui.QVBoxLayout()
            spacer = QtGui.QSpacerItem(20,40)
            spacer2 = QtGui.QSpacerItem(10,40)
    
            font = QtGui.QFont()
            font.setFamily("Rod")
            font.setPointSize(23)
            font2 = QtGui.QFont()
            font2.setFamily("Rod")
            font2.setPointSize(18)
            font3 = QtGui.QFont()
            font3.setFamily("Rod")
            font3.setPointSize(13)
    
            #Plotting Methods from Matplotlib
            self.figure = plt.figure()
            self.canvas = FigureCanvas(self.figure)
            self.canvas.setMaximumHeight(525)
            self.canvas.setMaximumHeight(725)
            self.toolbar = NavigationToolbar(self.canvas, self)
    
    
            #Labels
            self.label = QtGui.QLabel(self)
            self.label.setFont(font)
            self.label.setText("  Welcome to PPMS Data Analyser")
            self.label.setMaximumSize(625,30)
    
            label2 = QtGui.QLabel(self)
            label2.setFont(font2)
            label2.setText("Select Plot:")
    
            x_label = QtGui.QLabel(self)
            x_label.setFont(font3)
            x_label.setText("x axis:")
    
            y_label = QtGui.QLabel(self)
            y_label.setFont(font3)
            y_label.setText("y axis:")
    
            #Push Buttons
            fileSelect = QtGui.QPushButton('Select File')
            fileSelect.setMaximumSize(70,25)
            fileSelect.clicked.connect(self.plot)
            goPlot = QtGui.QPushButton('Plot')
            goPlot.setMaximumSize(60,20)
            goPlot.clicked.connect(self.plot)
    
    
    
    
    
            # x axis radio buttons
            groupBox = QtGui.QGroupBox()
            radio1 = QtGui.QRadioButton("Time")
            radio2 = QtGui.QRadioButton("Delta T")
            radio3 = QtGui.QRadioButton("Delta V")
            radioa = QtGui.QRadioButton("Hot Side Temp")
            radiob = QtGui.QRadioButton("Cold Side Temp")
            radioc = QtGui.QRadioButton("System Temp")
            radio2.setChecked(True)
    
    
            # Vertically aligns these buttons
            vbox = QtGui.QVBoxLayout()
            vbox.addWidget(x_label)
            vbox.addWidget(radio1)
            vbox.addWidget(radio2)
            vbox.addWidget(radio3)
            vbox.addWidget(radioa)
            vbox.addWidget(radiob)
            vbox.addWidget(radioc)
            vbox.addStretch(1)
            groupBox.setLayout(vbox)
    
            # y axis radio buttons
            groupBox2 = QtGui.QGroupBox()
            radio12 = QtGui.QRadioButton("Time")
            radio22 = QtGui.QRadioButton("Delta T")
            radio32 = QtGui.QRadioButton("Delta V")
            radioa2 = QtGui.QRadioButton("Hot Side Temp")
            radiob2 = QtGui.QRadioButton("Cold Side Temp")
            radioc2 = QtGui.QRadioButton("System Temp")
            radio32.setChecked(True)
    
            # Vertically aligns these buttons
            vbox2 = QtGui.QVBoxLayout()
            vbox2.addWidget(y_label)
            vbox2.addWidget(radio12)
            vbox2.addWidget(radio22)
            vbox2.addWidget(radio32)
            vbox2.addWidget(radioa2)
            vbox2.addWidget(radiob2)
            vbox2.addWidget(radioc2)
            vbox2.addStretch(1)
            groupBox2.setLayout(vbox2)
    
            #Box for 2 radio boxes
            hbox0 = QtGui.QHBoxLayout()
            hbox0.addWidget(groupBox)
            hbox0.addWidget(groupBox2)
            hbox0.addStretch(0)
    
            Left.addWidget(self.label)
            Left.addWidget(self.canvas)
            Left.addWidget(self.toolbar)
            Right.addItem(spacer)
            Right.addWidget(fileSelect)
            Right.addItem(spacer)
            Right.addWidget(label2)
            Right.addLayout(hbox0)
            Right.addWidget(goPlot)
            #Right.addLayout(hbox0)
    
            layout.addLayout(Left)
            layout.addLayout(Right)
    
            self.central_widget.setLayout(layout)
    
        def plot(self):
            ax = self.figure.add_subplot(111)
            ax.hold(False)
            ax.plot([1,2],[3,4])
            plt.grid()
            plt.title('Test Plot')
            self.canvas.draw()
    
    
    
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
    
        main = Window()
        main.setWindowTitle('PPMS Seebeck Calculator')
        main.show()
    
        sys.exit(app.exec_())
    

    That's what I did:

    1) Created central_widget:

    self.central_widget = QtGui.QWidget()
    self.setCentralWidget(self.central_widget)
    

    2) To avoid this warning: QLayout: Attempting to add QLayout "" to Window "", which already has a layout I changed

    layout = QtGui.QHBoxLayout(self)
    Right = QtGui.QVBoxLayout(self)
    Left = QtGui.QVBoxLayout(self)
    

    to

    layout = QtGui.QHBoxLayout()
    Right = QtGui.QVBoxLayout()
    Left = QtGui.QVBoxLayout()
    

    and commented second Right.addLayout(hbox0)

    3) Setted layout for central_widget : self.central_widget.setLayout(layout)