\

Building a Professional-looking GUI with PyQt (Part 1)

Create a form quickly: QFormLayout

If you’ve been creating forms to perform operations such as entering data into a database, QFormLayout is for you. This class lays out the widgets in a two-column layout. The first column usually displays labels that describe the expected input, and the second column usually contains input widgets that allow the user to enter or edit data, such as QLineEdit, QComboBox, or QSpinBox.

To add widgets to the form layout, use.addrow (). There are multiple variables to this method, but in most cases, you can choose from one of the following:

  • .addrow (Label, field)Add a new row to the bottom of the form layout. The line should contain oneQLabelObject (label) and an input widget (field)).
  • .addrow (labelText, Field)Automatically create and add a bandlabelTextAs new to its textQLabelObject. field. fieldContains an input widget.

Here is an example application that uses the QFormLayout object to arrange widgets:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QFormLayout,
    QLabel,
    QLineEdit,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QFormLayout Example")
        self.resize(270.110)
        # Create a QHBoxLayout instance
        layout = QFormLayout()
        # Add widgets to the layout
        layout.addRow("Name:", QLineEdit())
        layout.addRow("Job:", QLineEdit())
        emailLabel = QLabel("Email:")
        layout.addRow(emailLabel, QLineEdit())
        # Set the layout on the application's window self.setLayout(layout) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())Copy the code

In line 17, create a QFormLayout object. Then, on lines 19 through 22, add some rows to the layout. Notice that on lines 19 and 20, you use the second variable of the method, and on line 22, you use the first variable, passing the QLabel object to.addrow () as the first argument.

If you run this code, you will see the following window on the screen:

With QFormLayout, you can organize widgets in two columns. The first column contains labels that ask the user to provide some information. The second column shows the widgets that allow the user to enter or edit that information.

Nested layouts to build complex GUIs

You can use nested layouts to create complex GUIs that are difficult to create with one of the general PyQt layout managers. To do this, you need to call.addLayout () on the external layout. In this way, the internal layout becomes a child of the external layout.

Suppose you want to create a dialog box that displays labels and line edits in the form layout, and you want to place multiple check boxes in the vertical layout below these widgets. Here is a model of how your dialog should look:

The blue rectangle represents your external layout. The green rectangle is the form layout that will keep the labels and lines editable. The red rectangle is the vertical layout used to hold the option check boxes. Both the green layout and the red layout are nested within the blue layout, which is vertical.

Here is an example of how to build this layout using PyQt:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QCheckBox,
    QFormLayout,
    QLineEdit,
    QVBoxLayout,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Nested Layouts Example")
        # Create an outer layout
        outerLayout = QVBoxLayout()
        # Create a form layout for the label and line edit
        topLayout = QFormLayout()
        # Add a label and a line edit to the form layout
        topLayout.addRow("Some Text:", QLineEdit())
        # Create a layout for the checkboxes
        optionsLayout = QVBoxLayout()
        # Add some checkboxes to the layout
        optionsLayout.addWidget(QCheckBox("Option one"))
        optionsLayout.addWidget(QCheckBox("Option two"))
        optionsLayout.addWidget(QCheckBox("Option three"))
        # Nest the inner layouts into the outer layout
        outerLayout.addLayout(topLayout)
        outerLayout.addLayout(optionsLayout)
        # Set the window's main layout self.setLayout(outerLayout) if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())Copy the code

This is what you do in this code:

  • In line 17, you create an external or top-level layout that will be used as the parent layout and the main layout for the window. In this case, useQVBoxLayoutThis is because you want to align the widgets vertically on the form. In your model, this is the blue layout.
  • In line 19, you create a form layout to hold labels and line edits.
  • In line 21, add the required widgets to the layout. This is equivalent to your green layout.
  • In line 23, you will create a vertical layout to hold the check boxes.
  • On lines 25 through 27, add the required check boxes. Here is your red layout.
  • On lines 29 and 30, willtopLayoutandoptionsLayoutNested withinoutsideLayoutUnder.

If you run the application, you will see a window similar to the following:

In this application, you nested two different layouts under an external layout to create a regular layout for the window. At the top of the window, use a horizontal layout to place labels and line edits. Then, use a vertical layout to place check boxes below it.

Use multi-page layouts and widgets

So far, you’ve seen how to arrange widgets in the Windows of your application using traditional or generic layout managers. These layout managers arrange widgets on a one-page layout. In other words, your GUI will always display the same set of widgets to the user.

Sometimes you need to create a layout that displays a different set of widgets in response to some user action on the GUI. For example, if you want to create a preference dialog box for a given application, you might want to show the user a tab-based or multi-page layout, where each TAB or page contains a different set of closely related options. Each time a user clicks a TAB or page, the application displays a different set of widgets.

PyQt provides a built-in layout called QStackedLayout and some handy widgets (such as Qtab Widgets) that will allow you to create this multi-page layout. The next few sections walk you through some of these tools.

Create the widget stack

QStackedLayout provides a layout manager that allows you to arrange widgets on a stack, one on top of another. In this layout, only one widget is visible at any given time.

To populate a stacked layout with widgets, you call.addWidget () on the layout object. This adds each widget to the end of the list of widgets within the layout. You can also use.insertwidget (index) or.removeWidget (widget), respectively, to insert or remove a widget at a given location in the widget list.

Each widget in the widget list is displayed as a separate page. If you want to display multiple widgets on a page, use the QWidget object for each page and set the appropriate widget layout for the page widgets. If you want to get the total number of widgets (pages) in your layout, call.count ().

The important thing to remember when using the QStackedLayout object is that you need to explicitly provide a mechanism for switching between pages. Otherwise, your layout will always show the user the same page. To switch between pages, you need to call.setCurrentIndex () on the layout object.

Here is an example of how to switch between pages using a stacked layout with combo boxes:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QComboBox,
    QFormLayout,
    QLineEdit,
    QStackedLayout,
    QVBoxLayout,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QStackedLayout Example")
        # Create a top-level layout
        layout = QVBoxLayout()
        self.setLayout(layout)
        # Create and connect the combo box to switch between pages
        self.pageCombo = QComboBox()
        self.pageCombo.addItems(["Page 1"."Page 2"]) self.pageCombo.activated.connect(self.switchPage) # Create the stacked layout self.stackedLayout = QStackedLayout() #  Create the first page self.page1 = QWidget() self.page1Layout = QFormLayout() self.page1Layout.addRow("Name:", QLineEdit())
        self.page1Layout.addRow("Address:". QLineEdit()) self.page1.setLayout(self.page1Layout) self.stackedLayout.addWidget(self.page1) # Create the second page self.page2 = QWidget() self.page2Layout = QFormLayout() self.page2Layout.addRow("Job:", QLineEdit())
        self.page2Layout.addRow("Department:". QLineEdit()) self.page2.setLayout(self.page2Layout) self.stackedLayout.addWidget(self.page2) # Add the combo box and the  stacked layout to the top-level layout layout.addWidget(self.pageCombo) layout.addLayout(self.stackedLayout) def switchPage(self): self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
Copy the code

In lines 21 through 23, you will create a QComboBox object that will allow you to switch between pages in the layout. Then, add two options to the combo box of the list and connect them to a. SwitchPage () designed to handle page switching.

Inside.SwitchPage (), you call.setCurrentIndex () on the layout object, passing the current index of the combo box as an argument. This way, when the user changes the options in the combo box, the page on the stacked layout changes accordingly.

On line 25, create the QStackedLayout object. On lines 27 to 32, add the first page to the layout, and on lines 34 to 39, add the second page to the layout. Each page is represented by a QWidget object that contains multiple widgets in a convenient layout.

The final step to get everything running is to add the combo box and layout to the main layout of your application.

Now, your application behaves like this:

In this case, you have two pages in your application layout. Each page is represented by a QWidget object. When you select a new page in the combo box at the top of the window, the layout changes to show the selected page.

In addition to stacked layouts and stacked widgets, you can use QtabWidgets to create multi-page user interfaces. You’ll learn how in the next section.

Tag widgets that use PyQt

Another popular way to create multi-page arrangements in PyQt is to use a class called QTabWidget. This class provides TAB bars and page areas. You can use the TAB bar to switch between pages and use the page area to display the page associated with the selected TAB.

By default, the TAB bar is located at the top of the page area. However, this behavior can be changed using.settabPosition () and one of four possible TAB positions:

To add a TAB to the TAB widget, use.addtab (). This method has two implementations of variables or overloads:

1. AddTab (page, label)

2,. AddTab (Page, icon, label)

In both cases, the method adds a new label, which is the label title. .page must be a widget that represents the page associated with the TAB at hand.

In the second variable of the method, the icon must be a QIcon object. If you pass the icon to.addTab (), it will appear to the left of the label title.

A common practice when creating tabbed widgets is to use QWidget objects for each page. This allows you to add additional widgets to the page using a layout that contains the widgets you need.

Most of the time, you will use the label widget to create dialog boxes for GUI applications. This layout allows you to provide users with multiple options in a relatively small space. You can also use a tabbed system to organize options according to some sort of criteria.

Here is a sample application that shows the basics of how to create and use QTabWidget objects:

import sys

from PyQt5.QtWidgets import (
    QApplication,
    QCheckBox,
    QTabWidget,
    QVBoxLayout,
    QWidget,
)

class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("QTabWidget Example")
        self.resize(270.110) # Create a top-level layout layout = QVBoxLayout() self.setLayout(layout) # Create the tab widget with two tabs tabs =  QTabWidget() tabs.addTab(self.generalTabUI(),"General")
        tabs.addTab(self.networkTabUI(), "Network")
        layout.addWidget(tabs)

    def generalTabUI(self):
        """Create the General page UI."""
        generalTab = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(QCheckBox("General Option 1"))
        layout.addWidget(QCheckBox("General Option 2"))
        generalTab.setLayout(layout)
        return generalTab

    def networkTabUI(self):
        """Create the Network page UI."""
        networkTab = QWidget()
        layout = QVBoxLayout()
        layout.addWidget(QCheckBox("Network Option 1"))
        layout.addWidget(QCheckBox("Network Option 2"))
        networkTab.setLayout(layout)
        return networkTab

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())
Copy the code

In this example, you use the TAB widget to present the user with a succinct dialog box that shows the options associated with the General and Networking sections of the hypothetical preference menu. On line 20, create the QTabWidget object. Then, use.addTab () to add two tabs to the TAB widget.

In.generalTabui () and networkTabUI (), create a specific GUI for each TAB. To do this, you can use the QWidget object, the QVBoxLayout object, and some check boxes to hold the options.

If you run the application now, the following dialog will appear on the screen:

You have a fully functional tab-based GUI. Note that to switch between pages, simply click the appropriate TAB.

Read more

Build a professional-looking GUI with PyQt (part 1) \

Getting started with PyQt5 GUI Application Toolkit (1) \

Getting started with PyQt5 GUI Application Toolkit (2) \

Special recommendation \

Programmer’s guide to fish

For your selection of Silicon Valley geeks,

From FLAG giant developers, technology, venture capital first-hand news

\

Click below to read the article and join the community