pythonpyqtpyqt5qwizardqwizardpage

Center resized Qwizard page


I have a Qwizard with 2 pages.

When the wizard is opened, it is centered in the middle of the screen.

The first page is smaller than the second page.

When next is clicked and the second page is displayed, it adds the extra items to the bottom of the first page but does not re-center the page.

On smaller screens this means that the buttons are off-screen at the bottom and cannot be seen unless the user moves the window up.

I have tried to use standard QT widget centering but Qwizard does not seem to respond to this.

How can I re center the second page of the wizard so that the whole widget is displayed?

import sys

from PyQt5.QtCore import Qt, QPoint, QIODevice, QDateTime, QSize, QObject, QProcess, pyqtSignal, QThread, QEvent, QTimer, QBasicTimer
from PyQt5.QtWidgets import  QStyle, QWidget, QMainWindow, QCompleter, QProgressBar, QFileDialog, QApplication, qApp, QLineEdit, QLabel, QComboBox, QWizard, QWizardPage, QPushButton, QVBoxLayout, QShortcut, QMessageBox, QDesktopWidget, QHBoxLayout
from PyQt5.QtGui import QPainter, QFont, QIcon, QPixmap, QPalette, QLinearGradient, QColor, QBrush, QCursor


class Wizard(QWizard):
    # Initilisation of the UI and Wizard
    def __init__(self, parent=None):
        super(Wizard, self).__init__(parent)


        self.addPage(EnterToken(self))           
        self.addPage(EnterCode(self))                

class EnterToken(QWizardPage):
    def __init__(self, parent=None):
        super(EnterToken, self).__init__(parent)

        # Spacer blank label
        self.spacer = QLabel()

        # Enter Token Widgets
        self.label1 = QLabel()
        self.enter_token_box = QLineEdit()

        # empty text box for button
        self.empty = QLineEdit()

        self.btn = QPushButton('Enter Token')

        # layout options
        layout = QVBoxLayout()

        layout.addWidget(self.spacer)

        layout.addWidget(self.label1)
        layout.addWidget(self.enter_token_box)
        layout.addWidget(self.btn)

        self.setLayout(layout)


    def _EnterToken(self):
        """ Method for processing user input after the button is pressed"""
        text = self.enter_token_box.text()


class EnterCode(QWizardPage):
    """ Sensor Code Entry """

    def __init__(self, parent=None):
        super(EnterCode, self).__init__(parent)

        # Spacer Label
        self.spacer = QLabel()

        self._five_digit = QLineEdit(self)
        self.code_combo = QComboBox(self)
        self.label1 = QLabel()

        self.lineedit1 = QLineEdit(self)
        self.lineedit2 =QLineEdit(self)
        self.lineedit3 = QLineEdit(self)
        self.lineedit4 = QLineEdit(self)
        self.lineedit5 = QLineEdit(self)
        self.lineedit6 = QLineEdit(self)
        self.lineedit7 = QLineEdit(self)
        self.lineedit8 = QLineEdit(self)
        self.lineedit9 = QLineEdit(self)
        self.lineedit10 = QLineEdit(self)


        self.code_combo_list = [
            'Years', 'Months', 'Weeks', 'Days', 'Hours', 'Years', 'Months', 'Weeks', 'Days', 'Hours']
        for x in self.code_combo_list:
            self.code_combo.addItem(x)

        # num of logs combo box
        self.enter_num_logs = QLineEdit(self)
        self.num_logs_combo = QComboBox(self)
        self.logs_label = QLabel()


        self.num_logs_combo_list = [
            'Years', 'Months', 'Weeks', 'Days', 'Hours', 'Years', 'Months', 'Weeks', 'Days', 'Hours']
        for x in self.num_logs_combo_list:
            self.num_logs_combo.addItem(x)

        # ~buttons
        self.btn = QPushButton('Download Data')

        layout = QVBoxLayout()

        layout.addWidget(self.spacer)
        layout.addWidget(self.label1)
        layout.addWidget(self.code_combo)
        layout.addWidget(self._five_digit)

        layout.addWidget(self.lineedit1)
        layout.addWidget(self.lineedit2)
        layout.addWidget(self.lineedit3)
        layout.addWidget(self.lineedit4)
        layout.addWidget(self.lineedit5)
        layout.addWidget(self.lineedit6)
        layout.addWidget(self.lineedit7)
        layout.addWidget(self.lineedit8)
        layout.addWidget(self.lineedit9)
        layout.addWidget(self.lineedit10)


        layout.addWidget(self.logs_label)
        layout.addWidget(self.num_logs_combo)
        layout.addWidget(self.enter_num_logs)

        layout.addWidget(self.btn)

        self.setLayout(layout)



if __name__ == '__main__':

Solution

  • If you want to center the window you must do it when it is visible, in this case the currentIdChanged signal must be used, but when the slot is called even the new window is not visible so we will use a QTimer to update it an instant later.

    class Wizard(QWizard):
        def __init__(self, parent=None):
            super(Wizard, self).__init__(parent)
            self.addPage(EnterToken(self))           
            self.addPage(EnterCode(self))
            self.currentIdChanged.connect(self.onCurrentIdChanged)
    
        def onCurrentIdChanged(self):
            QTimer.singleShot(0, self.center_widget)
    
        def center_widget(self):
            self.window().setGeometry(
                QStyle.alignedRect(
                    Qt.LeftToRight, 
                    Qt.AlignCenter,
                    self.window().size(), 
                    QApplication.desktop().availableGeometry())
            )