添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
注册/登录

用PyQt打造具有专业外观的GUI(中篇)

开发 后端
您可以使用嵌套布局来创建复杂的GUI,而使用通用PyQt的布局管理器之一很难创建这些GUI。

用 PyQt 打造具有专业外观的GUI(上篇)

快速创建表单:QFormLayout

如果您一直在创建表单以执行将数据输入数据库等操作,那么QFormLayout适合您。此类将小部件布置为两列布局。第一列通常显示描述预期输入的标签,第二列通常包含允许用户输入或编辑数据的输入小部件,例如QLineEdit,QComboBox或QSpinBox。

要将小部件添加到表单布局,请使用.addRow()。此方法有多种变量,但是在大多数情况下,您可以从以下两种进行选择:

  • .addRow(label,field)将新行添加到表单布局的底部。该行应包含一个QLabel对象(label)和一个输入小部件(field))。
  • .addRow(labelText,field)自动创建并添加带有labelText作为其文本的新QLabel对象。字段. field包含一个输入小部件。
  • 这是一个使用QFormLayout对象排列小部件的示例应用程序:

    1. import sys  
    2. from PyQt5.QtWidgets import (  
    3.     QApplication,  
    4.     QFormLayout,  
    5.     QLabel,  
    6.     QLineEdit, 
    7.     QWidget,  
    8.  
    9. class Window(QWidget):  
    10.     def __init__(self):  
    11.         super().__init__()  
    12.         self.setWindowTitle("QFormLayout Example")  
    13.         self.resize(270, 110)  
    14.         # Create a QHBoxLayout instance  
    15.         layout = QFormLayout()  
    16.         # Add widgets to the layout  
    17.         layout.addRow("Name:", QLineEdit())  
    18.         layout.addRow("Job:", QLineEdit())  
    19.         emailLabel = QLabel("Email:")  
    20.         layout.addRow(emailLabel, QLineEdit())  
    21.         # Set the layout on the application's window  
    22.         self.setLayout(layout)  
    23. if __name__ == "__main__":  
    24.     app = QApplication(sys.argv)  
    25.     window = Window()  
    26.     window.show() 
    27.      sys.exit(app.exec_()) 

    在第17行,创建一个QFormLayout对象。然后,在第19至22行上,向布局中添加一些行。请注意,在第19行和第20行,您使用方法的第二个变量,在第22行,您使用第一个变量,将QLabel对象作为第一个参数传递给.addRow()。

    如果您运行此代码,则会在屏幕上看到以下窗口:

    [[359059]]

    使用QFormLayout,可以以两列的方式组织小部件。第一列包含标签,要求用户提供一些信息。第二列显示允许用户输入或编辑该信息的小部件。

    嵌套布局以构建复杂的GUI

    您可以使用嵌套布局来创建复杂的GUI,而使用通用PyQt的布局管理器之一很难创建这些GUI。为此,您需要在外部布局上调用.addLayout()。这样,内部布局成为外部布局的子级。

    假设您需要创建一个对话框,该对话框在表单布局中显示标签和行编辑,并且在这些小部件下方您要在垂直布局中放置多个复选框。这是您的对话框外观的模型:

    蓝色矩形代表您的外部布局。绿色矩形是将保留标签和行编辑的表单布局。红色矩形是用于容纳选项复选框的垂直布局。绿色布局和红色布局都嵌套在蓝色布局中,蓝色布局是垂直布局。

    这是一个如何使用PyQt构建此布局的示例:

    1. import sys  
    2. from PyQt5.QtWidgets import (  
    3.     QApplication,  
    4.     QCheckBox,  
    5.     QFormLayout,  
    6.     QLineEdit,  
    7.     QVBoxLayout,  
    8.     QWidget,  
    9.  
    10. class Window(QWidget):  
    11.     def __init__(self):  
    12.         super().__init__()  
    13.         self.setWindowTitle("Nested Layouts Example")  
    14.         # Create an outer layout  
    15.         outerLayout = QVBoxLayout()  
    16.         # Create a form layout for the label and line edit  
    17.         topLayout = QFormLayout()  
    18.         # Add a label and a line edit to the form layout  
    19.         topLayout.addRow("Some Text:", QLineEdit())  
    20.         # Create a layout for the checkboxes  
    21.         optionsLayout = QVBoxLayout()  
    22.         # Add some checkboxes to the layout  
    23.         optionsLayout.addWidget(QCheckBox("Option one"))  
    24.         optionsLayout.addWidget(QCheckBox("Option two"))  
    25.         optionsLayout.addWidget(QCheckBox("Option three"))  
    26.         # Nest the inner layouts into the outer layout  
    27.         outerLayout.addLayout(topLayout)  
    28.         outerLayout.addLayout(optionsLayout)  
    29.         # Set the window's main layout  
    30.         self.setLayout(outerLayout)  
    31. if __name__ == "__main__":  
    32.     app = QApplication(sys.argv)  
    33.     window = Window()  
    34.     window.show()  
    35.     sys.exit(app.exec_()) 

    这是您在此代码中执行的操作:

  • 在第17行,您将创建外部或顶层布局,将其用作父布局和窗口的主布局。在这种情况下,使用QVBoxLayout是因为您希望将小部件垂直排列在窗体上。在您的模型中,这是蓝色布局。
  • 在第19行,您创建一个表单布局来保存标签和行编辑。
  • 在第21行,将所需的小部件添加到布局中。这等效于您的绿色布局。
  • 在第23行,您将创建一个垂直布局来容纳复选框。
  • 在第25至27行上,添加所需的复选框。这是您的红色布局。
  • 在第29和30行上,将topLayout和optionsLayout嵌套在outsideLayout下。
  • 如果您运行该应用程序,则会看到类似以下的窗口:

    在此应用程序中,您将两个不同的布局嵌套在外部布局下,以为窗口创建常规布局。在窗口顶部,使用水平布局放置标签和行编辑。然后,使用垂直布局在其下方放置一些复选框。

    使用多页布局和小部件

    到目前为止,您已经了解了如何使用传统或通用布局管理器在应用程序的窗口中排列小部件。这些布局管理器将小部件安排在单页布局上。换句话说,您的GUI将始终向用户显示相同的窗口小部件集。

    有时您需要创建一个布局,以显示一组不同的窗口小部件,以响应GUI上的某些用户操作。例如,如果要为给定的应用程序创建首选项对话框,则可能需要向用户显示基于选项卡或多页的布局,其中每个选项卡或页面都包含一组不同的紧密相关的选项。每次用户单击选项卡或页面时,应用程序都会显示一组不同的小部件。

    PyQt提供了一个称为QStackedLayout的内置布局以及一些方便的小部件(例如QTabWidget),这些小部件将允许您创建这种多页布局。接下来的几节将带您逐步了解其中一些工具。

    创建小部件堆栈

    QStackedLayout提供了一个布局管理器,该管理器允许您将小部件排列在一个堆栈上,一个放在另一个上。在这种布局中,给定时间仅可见一个小部件。

    要使用小部件填充堆叠的布局,您需要在布局对象上调用.addWidget()。这会将每个小部件添加到布局内部小部件列表的末尾。您还可以分别使用.insertWidget(index)或.removeWidget(widget)在小部件列表中的给定位置插入或删除小部件。

    小部件列表中的每个小部件都显示为独立页面。如果要在页面上显示多个窗口小部件,请对每个页面使用QWidget对象,并为页面窗口小部件设置适当的窗口小部件布局。如果需要获取布局中小部件(页面)的总数,则可以调用.count()。

    使用QStackedLayout对象时要记住的重要一点是,您需要显式提供一种在页面之间切换的机制。否则,您的布局将始终向用户显示同一页面。要在页面之间切换,您需要在布局对象上调用.setCurrentIndex()。

    这是一个示例,展示了如何使用带有组合框的堆叠式布局在页面之间进行切换:

    1. import sys  
    2. from PyQt5.QtWidgets import ( 
    3.     QApplication,  
    4.     QComboBox,  
    5.     QFormLayout,  
    6.     QLineEdit,  
    7.     QStackedLayout,  
    8.     QVBoxLayout,  
    9.     QWidget,  
    10.  
    11. class Window(QWidget):  
    12.     def __init__(self):  
    13.         super().__init__()  
    14.         self.setWindowTitle("QStackedLayout Example")  
    15.         # Create a top-level layout  
    16.         layout = QVBoxLayout()  
    17.         self.setLayout(layout)  
    18.         # Create and connect the combo box to switch between pages  
    19.         self.pageCombo = QComboBox()  
    20.         self.pageCombo.addItems(["Page 1", "Page 2"])  
    21.         self.pageCombo.activated.connect(self.switchPage)  
    22.         # Create the stacked layout  
    23.         self.stackedLayout = QStackedLayout()  
    24.         # Create the first page  
    25.         self.page1 = QWidget()  
    26.         self.page1Layout = QFormLayout()  
    27.         self.page1Layout.addRow("Name:", QLineEdit())  
    28.         self.page1Layout.addRow("Address:", QLineEdit())  
    29.         self.page1.setLayout(self.page1Layout)  
    30.         self.stackedLayout.addWidget(self.page1)  
    31.         # Create the second page  
    32.         self.page2 = QWidget()  
    33.         self.page2Layout = QFormLayout()  
    34.         self.page2Layout.addRow("Job:", QLineEdit())  
    35.         self.page2Layout.addRow("Department:", QLineEdit())  
    36.         self.page2.setLayout(self.page2Layout)  
    37.         self.stackedLayout.addWidget(self.page2)  
    38.         # Add the combo box and the stacked layout to the top-level layout  
    39.         layout.addWidget(self.pageCombo)  
    40.         layout.addLayout(self.stackedLayout)  
    41.     def switchPage(self): 
    42.         self.stackedLayout.setCurrentIndex(self.pageCombo.currentIndex())  
    43. if __name__ == "__main__":  
    44.     app = QApplication(sys.argv)  
    45.     window = Window()  
    46.     window.show()  
    47.     sys.exit(app.exec_()) 

    在第21至23行,您将创建一个QComboBox对象,该对象将允许您在布局中的页面之间进行切换。然后,在列表的组合框中添加两个选项,并将其连接到旨在处理页面切换的.switchPage()。

    在.switchPage()内部,您在布局对象上调用.setCurrentIndex(),将组合框的当前索引作为参数传递。这样,当用户更改组合框中的选项时,堆叠版式上的页面将相应地更改。

    在第25行上,创建QStackedLayout对象。在第27至32行上,将第一页添加到布局中,在第34至39行上,将第二页添加到布局中。每个页面都由一个QWidget对象表示,该对象以方便的布局包含多个小部件。

    使一切正常运行的最后一步是将组合框和布局添加到应用程序的主布局。

    现在,您的应用程序的行为如下:

    在这种情况下,您的应用程序布局中有两个页面。每个页面由一个QWidget对象表示。当您在窗口顶部的组合框中选择一个新页面时,布局将更改以显示所选页面。

    除了堆叠的布局和堆叠的小部件,您还可以使用QTabWidget创建多页用户界面。您将在下一节中学习如何操作。

    使用PyQt的标签小部件

    在PyQt中创建多页排列的另一种流行方式是使用称为QTabWidget的类。此类提供标签栏和页面区域。您可以使用选项卡栏在页面之间切换,并使用页面区域显示与所选选项卡关联的页面。

    默认情况下,选项卡栏位于页面区域的顶部。但是,可以使用.setTabPosition()和四个可能的选项卡位置之一来更改此行为:

    要将选项卡添加到选项卡小部件,请使用.addTab()。此方法有两个变量或重载的实现:

    1、.addTab(page, label)

    2、.addTab(page, icon, label)

    在这两种情况下,该方法都会添加一个新标签,label为标签标题。. page必须是一个小部件,代表与手边的选项卡关联的页面。

    在该方法的第二变量中,图标必须是QIcon对象。如果您将图标传递给.addTab(),则该图标将显示在标签标题的左侧。

    创建选项卡小部件时的常见做法是为每个页面使用QWidget对象。这样,您就可以使用包含所需窗口小部件的布局向页面添加额外的窗口小部件。

    大多数情况下,您将使用标签小部件为GUI应用程序创建对话框。这种布局允许您在相对较小的空间中为用户提供多个选项。您还可以利用选项卡系统根据一些分类标准来组织选项。

    这是一个示例应用程序,显示了如何创建和使用QTabWidget对象的基础知识:

    1. import sys  
    2. from PyQt5.QtWidgets import (  
    3.     QApplication,  
    4.     QCheckBox,  
    5.     QTabWidget,  
    6.     QVBoxLayout,  
    7.     QWidget,  
    8.  
    9. class Window(QWidget):  
    10.     def __init__(self):  
    11.         super().__init__()  
    12.         self.setWindowTitle("QTabWidget Example")  
    13.         self.resize(270, 110)  
    14.         # Create a top-level layout  
    15.         layout = QVBoxLayout()  
    16.         self.setLayout(layout)  
    17.         # Create the tab widget with two tabs  
    18.         tabs = QTabWidget()  
    19.         tabs.addTab(self.generalTabUI(), "General")  
    20.         tabs.addTab(self.networkTabUI(), "Network")  
    21.         layout.addWidget(tabs)  
    22.     def generalTabUI(self):  
    23.         """Create the General page UI."""  
    24.         generalTab = QWidget()  
    25.         layout = QVBoxLayout()  
    26.         layout.addWidget(QCheckBox("General Option 1"))  
    27.         layout.addWidget(QCheckBox("General Option 2"))  
    28.         generalTab.setLayout(layout)  
    29.         return generalTab  
    30.     def networkTabUI(self):  
    31.         """Create the Network page UI."""  
    32.         networkTab = QWidget()  
    33.         layout = QVBoxLayout()  
    34.         layout.addWidget(QCheckBox("Network Option 1"))  
    35.         layout.addWidget(QCheckBox("Network Option 2"))  
    36.         networkTab.setLayout(layout)  
    37.         return networkTab  
    38. if __name__ == "__main__":  
    39.     app = QApplication(sys.argv)  
    40.     window = Window()  
    41.     window.show()  
    42.     sys.exit(app.exec_()) 

    在此示例中,您使用选项卡小部件向用户显示一个简洁的对话框,该对话框显示与假设首选项菜单的“常规”和“网络”部分相关的选项。在第20行上,创建QTabWidget对象。然后,使用.addTab()将两个选项卡添加到选项卡小部件。

    在.generalTabUI()和networkTabUI()中,为每个选项卡创建特定的GUI。为此,您可以使用QWidget对象,QVBoxLayout对象和一些复选框来保存选项。

    如果立即运行该应用程序,则屏幕上将显示以下对话框:

    您有一个功能齐全的基于选项卡的GUI。请注意,要在页面之间切换,只需单击相应的选项卡。

    责任编辑:庞桂玉 Python中文社区(ID:python-china)
    点赞
    收藏