Python Forum
How to simplify widget creation?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to simplify widget creation?
#1
Hello,
I'm still quite inexperienced in writing my own classes and in using "self".
My question is about the MainWindow class.
How can I simplify widget creation, make it clearer?
It would be great if someone could help me...
Am I doing it reasonably correctly using "self"?

Thank you so much for the support!!

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        qr = self.frameGeometry()
        cp = self.screen().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

        self.w = QWidget()
        self.setCentralWidget(QWidget())
        self.setWindowTitle("abc")
        self.groupbox = QGroupBox("what do you have?")
        font = self.groupbox.font()
        font.setBold(True)
        self.groupbox.setFont(font)
        self.listbox_medium = QListWidget()
        self.listbox_medium2 = QListWidget()
        self.checkbox = QCheckBox("stack contains patchTpages")

        groupbox_layout = QVBoxLayout()
        groupbox_layout.addWidget(self.listbox_medium)
        groupbox_layout.addWidget(self.listbox_medium2)
        groupbox_layout.addWidget(self.checkbox)
        self.groupbox.setLayout(groupbox_layout)

        self.groupbox2 = QGroupBox("what would you like to receive?")
        font2 = self.groupbox2.font()
        font2.setBold(True)
        self.groupbox2.setFont(font2)
        self.listbox_target = QListWidget()
        self.groupbox3 = QGroupBox("move file(s) to")
        font3 = self.groupbox3.font()
        font3.setBold(True)
        self.groupbox3.setFont(font3)
        checkbox_move_to = QCheckBox("move file(s) to desired folder(s)")
        groupbox3_layout = QVBoxLayout()
        groupbox3_layout.addWidget(checkbox_move_to)
        self.groupbox3.setLayout(groupbox3_layout)

        groupbox2_layout = QVBoxLayout()
        groupbox2_layout.addWidget(self.listbox_target)
        groupbox2_layout.addWidget(self.groupbox3)
        self.groupbox2.setLayout(groupbox2_layout)

        self.groupbox4 = QGroupBox("which profile should be used?")
        font4 = self.groupbox4.font()
        font4.setBold(True)
        self.groupbox4.setFont(font4)
        self.listbox_profile = QListWidget()
        self.button_add_profile = QPushButton("add profile")
        self.button_clear_profile = QPushButton("clear profile")

        groupbox4u_layout = QHBoxLayout()
        groupbox4u_layout.addWidget(self.button_add_profile)
        groupbox4u_layout.addWidget(self.button_clear_profile)

        groupbox4_layout = QVBoxLayout()
        groupbox4_layout.addWidget(self.listbox_profile)
        groupbox4_layout.addLayout(groupbox4u_layout)
        self.groupbox4.setLayout(groupbox4_layout)

        self.button_apply_selection = QPushButton("apply selection")
        self.button_adjustments = QPushButton("adjustments")
        self.label = QLabel("abc")

        layoutBase = QVBoxLayout()
        layoutBase.addWidget(self.label)
        layoutBase.addWidget(self.groupbox)
        layoutBase.addWidget(self.groupbox2)
        layoutBase.addWidget(self.groupbox4)
        layoutBase.addWidget(self.button_apply_selection)
        layoutBase.addWidget(self.button_adjustments)

        self.w.setLayout(layoutBase)
        self.setCentralWidget(self.w)

        # fill listbox
        self.listbox_medium.insertItem(0, "paper")
        self.listbox_medium.insertItem(1, "file(s)")

        self.button_add_profile.clicked.connect(self.button_add_profile_clicked)
        self.button_clear_profile.clicked.connect(self.button_clear_profile_clicked)
        self.button_apply_selection.clicked.connect(self.button_apply_selection_clicked)
        self.button_adjustments.clicked.connect(self.button_adjustments_clicked)

    def button_add_profile_clicked(self):
        print("add_profile")

    def button_clear_profile_clicked(self):
        print("clear_profile")

    def button_adjustments_clicked(self):
        self.w = AdjustmentsWindow()
        self.w.show()

    def button_apply_selection_clicked(self):
        print("apply_selection")

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyleSheet(Path("stylesheet.qss").read_text())
    w = MainWindow()
    w.show()
    app.exec()
Reply
#2
You have no imports in your code.

Use unique names instead of numbers (groupbox2 groupbox3...)
Reply
#3
(Jul-21-2023, 03:55 PM)Axel_Erfurt Wrote: You have no imports in your code.

Use unique names instead of numbers (groupbox2 groupbox3...)

Ok, thanks...

Could you please give me a hint how to simplify the addWidget ?

groupbox_layout.addWidget(self.listbox_target)
 groupbox_layout.addWidget(self.groupbox_abc)
Could it be simplified using a for loop?

Thanks a lot...
Reply
#4
I got it:
        for x in [self.button_add_profile, self.button_clear_profile]:
            groupbox4u_layout.addWidget(x)
Reply
#5
What are you trying to simplify? It's just one line.
Reply
#6
(Jul-21-2023, 04:31 PM)Axel_Erfurt Wrote: What are you trying to simplify? It's just one line.

Okay,
that's right too...

(But I'm happy to get the for loop working...)

Have a nice evening...

thanks...
Reply
#7
You can do anything you want. For example:
from PySide6 import QtWidgets

class AutoLayout:
    """Mixin class that adds automatic layout management."""

    def __init__(self, *args, layout=QtWidgets.QVBoxLayout, **kwargs):
        super().__init__(*args, **kwargs)
        layout(self)

    def __setattr__(self, name, object):
        """Add QT widget objects to the layout."""
        super().__setattr__(name, object)
        if issubclass(type(object), QtWidgets.QWidget):
            self.layout().addWidget(object)


class Widget(AutoLayout, QtWidgets.QWidget):
    """QWidget with automatic layout."""


class GroupBox(AutoLayout, QtWidgets.QGroupBox):
    """QGroupBox with automatic layout."""


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("abc")
        self.w = Widget()
        self.setCentralWidget(self.w)

        self.w.groupbox = GroupBox("what do you have?")
        self.w.groupbox.listbox1 = QtWidgets.QListWidget()
        self.w.groupbox.listbox2 = QtWidgets.QListWidget()
        self.w.groupbox.checkbox = QtWidgets.QCheckBox("stack contains patchTpages")

        self.w.groupbox2 = GroupBox("what would you like to receive?")
        self.w.groupbox2.target = QtWidgets.QListWidget()

        self.w.groupbox2.groupbox = GroupBox("move file(s) to")
        self.w.groupbox2.groupbox.move_to = QtWidgets.QCheckBox(
            "move file(s) to desired folder(s)"
        )

        self.w.groupbox4 = GroupBox("which profile should be used?")
        self.w.groupbox4.profile = QtWidgets.QListWidget()
        self.w.groupbox4.buttons = Widget(layout=QtWidgets.QHBoxLayout())
        self.w.groupbox4.buttons.add_profile = QtWidgets.QPushButton("add profile")
        self.w.groupbox4.buttons.clear_profile = QtWidgets.QPushButton("clear profile")


if __name__ == "__main__":
    app = QtWidgets.QApplication()
    w = MainWindow()
    w.show()
    app.exec()
This code uses hierarchy to control layout. Adding a widget attribute to the Widget or GroupBox classes automatically adds the widget to the layout for that widget. With convenience comes restrictions. The restriction is that the widget object layout is tied to the widget screen layout. This places limitations on how you organize your code.

Things like this also mess up code analysis. The instance variables of a GroupBox or Widget object are all set externally, so you get no autocomplete help.

Got to admit that the code is much shorter. Is it worth it?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] How can I simplify this code? frednet 3 1,822 Feb-13-2020, 04:00 PM
Last Post: frednet

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020