掃二維碼與項目經(jīng)理溝通
我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
PyQt的布局管理器layout managers提供了一種用戶友好且高效的方式,可以在GUI上排列圖形組件或小部件。正確布置窗口小部件將使您的GUI應用程序看起來更加優(yōu)美和專業(yè)。學習有效地做到這一點是您使用Python和PyQt進行GUI應用程序開發(fā)和運行的一項基本技能。

成都創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè),為客戶提供成都網(wǎng)站設(shè)計、成都做網(wǎng)站、網(wǎng)頁設(shè)計開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗,各類網(wǎng)站都可以開發(fā),品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計,建網(wǎng)站費用,建網(wǎng)站多少錢,價格優(yōu)惠,收費合理。
在本教程中,您將學習:
有了這些知識和技能,您就可以使用Python和PyQt創(chuàng)建具有專業(yè)外觀的GUI應用程序。
在GUI上布置圖形元素
在創(chuàng)建圖形用戶界面(GUI)應用程序時,一個常見的問題是如何使圖形組件(按鈕,菜單,工具欄,標簽等)一致地放置在窗體和窗口上。此過程稱為GUI布局(GUI layout,),這是創(chuàng)建GUI應用程序的重要步驟。
之前如果要在窗口上布置圖形組件或窗口小部件,則可以采用以下方法之一:
第一種方法相當直接,但是至少具有以下缺點:
第二種方法更靈活。但是,它也有缺點:
即使您仍然可以使用這兩種方法中的任何一種來布局GUI,大多數(shù)時候您可能還是希望使用由最先進的GUI框架或工具包實現(xiàn)的第三種且更方便的方法:布局管理器layout managers。注意:在某些GUI框架(例如Tkinter)中,布局管理器也稱為geometry managers。
layout managers會根據(jù)您的特定需求自動在GUI上排列小 部件。它避免了第一種方法的兼容性缺點以及第二種方法的復雜計算。
在以下各節(jié)中,您將了解PyQt的內(nèi)置布局管理器以及如何使用它們有效地布局GUI應用程序的圖形組件。
多樣的PyQt布局形式
在PyQt中,小部件是用作GUI應用程序構(gòu)建塊的圖形組件。將一堆小部件放在窗口上以創(chuàng)建GUI時,需要給它們一些順序。您需要設(shè)置窗口小部件的大小和在窗口上的位置,還需要定義當用戶調(diào)整基礎(chǔ)窗口大小時它們的行為。
注意:PyQt5的官方文檔中有一些不完整的部分。要解決此問題,您可以查看PyQt4文檔,Qt for Python文檔或原始Qt文檔。
要在PyQt的窗口或窗體上排列小部件,可以使用以下技術(shù):
這些技術(shù)通常對應于上一節(jié)中介紹的用于布局GUI的三種不同方法。
再說一次,動態(tài)計算尺寸和位置可能是個好方法,但是大多數(shù)時候,使用布局管理器會更好。在PyQt中,布局管理器是提供所需功能以自動管理布局中小部件的大小,位置和調(diào)整大小行為的類。
使用布局管理器,您可以自動在任何母部件、容器、小部件內(nèi)排列子部件。使用布局管理器將確保您充分利用GUI上的可用空間,并確保當用戶調(diào)整窗口大小時,應用程序仍然可用。
布局管理器充當小部件和其他布局的容器時,要將小部件添加到布局管理器,請在當前布局上調(diào)用.addWidget()。要將布局添加到另一個布局,請在當前布局上調(diào)用.addLayout()。您將在“嵌套布局以構(gòu)建復雜的GUI”一節(jié)中更深入地了解嵌套布局。
將所有必需的小部件添加到布局管理器后,即可使用.setLayout()在給定的小部件上設(shè)置布局管理器。您可以在QWidget的任何子類(包括窗口或窗體)上設(shè)置布局管理器。
注意:QMainWindow是一個PyQt類,可用于創(chuàng)建main widow–style applications.。此類具有其自己的內(nèi)置布局管理器。因此,如果您使用的是QMainWindow,則通常不需要在主窗口對象上設(shè)置布局管理器。
布局中的所有窗口小部件都會自動設(shè)置為安裝布局的窗口小部件的子級,而不是布局本身。這是因為窗口小部件只能將其他窗口小部件(而不是布局)作為其父級。
PyQt的布局管理器提供了一些很酷的功能,可以使您在創(chuàng)建美觀的GUI應用程序時更加輕松:
從長遠來看,使用布局管理器還將極大地提高您的生產(chǎn)率并改善代碼的可維護性。
PyQt提供了四個通用布局管理器類:
在接下來的幾節(jié)中,您將學習如何使用這些通用布局管理器的基礎(chǔ)知識。
使用通用布局管理器
使用PyQt創(chuàng)建GUI應用程序時,通常會使用上一節(jié)末尾看到的四種通用布局中的一種或多種方法,來將窗口小部件布置在窗口和窗體上。
在接下來的幾節(jié)中,您將在一些示例的幫助下學習如何創(chuàng)建和使用四個通用布局管理器。
構(gòu)建水平布局:QHBoxLayout
Box layout managers從父布局或窗口小部件獲得的空間被分成多個盒子或單元格,然后使布局中的每個窗口小部件填充一個盒子。
QHBoxLayout是PyQt中兩個可用的框布局之一。這個布局管理器允許您水平排列小部件,一個接一個。這些小部件從左到右添加到布局中。這意味著您首先在代碼中添加的小部件將是布局中最左側(cè)的小部件。
要將小部件添加到QHBoxLayout對象,請在布局對象上調(diào)用.addWidget(widget,stretch,alignment)。此方法接受一個必需參數(shù)和兩個可選參數(shù):
下面是一個小型應用程序,顯示了如何使用QHBoxLayout創(chuàng)建水平布局。在此示例中,您將使用QPushButton對象根據(jù)將小部件添加到代碼中的順序更好地可視化每個小部件在布局中的放置位置:
- import sys
- from PyQt5.QtWidgets import (
- QApplication,
- QHBoxLayout,
- QPushButton,
- QWidget,
- )
- class Window(QWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("QHBoxLayout Example")
- # Create a QHBoxLayout instance
- layout = QHBoxLayout()
- # Add widgets to the layout
- layout.addWidget(QPushButton("Left-Most"))
- layout.addWidget(QPushButton("Center"), 1)
- layout.addWidget(QPushButton("Right-Most"), 2)
- # Set the layout on the application's window
- self.setLayout(layout)
- print(self.children())
- if __name__ == "__main__":
- app = QApplication(sys.argv)
- window = Window()
- window.show()
- sys.exit(app.exec_())
在第15行上,創(chuàng)建一個稱為layout的QHBoxLayout對象。在第17至19行,使用.addWidget()將三個按鈕添加到布局中。請注意,您分別在“居中”和“最右”按鈕中將1和2傳遞給了stretch參數(shù)。在第21行,使用.setLayout()將布局設(shè)置為窗口的頂級布局。
如果您運行此應用程序,則會在屏幕上看到以下窗口:
該窗口包含三個水平排列的按鈕。請注意,“最左鍵”按鈕對應于您在代碼中添加的第一個按鈕。因此,按鈕的顯示順序與您在代碼中添加按鈕的順序(從左到右)(從上到下)相同。
“居中”和“最右邊”按鈕具有不同的拉伸系數(shù),因此在調(diào)整窗口大小時,它們會按比例縮放。
此外,布局中的所有按鈕和布局本身都設(shè)置為Window的子級。這是由布局對象自動完成的,該布局對象在每個小部件上內(nèi)部調(diào)用.setParent()。在第17行上對print()的調(diào)用將在您的終端上打印Window的子代列表,以證明此行為。
構(gòu)建垂直布局:QVBoxLayout
QVBoxLayout垂直排列小部件,一個在另一個下方。您可以使用此類創(chuàng)建垂直布局,并從上到下排列窗口小部件。由于QVBoxLayout是另一個框布局,因此其.addWidget()方法的工作方式與QHBoxLayout中的相同。
下面是一個PyQt應用程序,它顯示了如何創(chuàng)建和使用QVBoxLayout對象在GUI中創(chuàng)建小部件的垂直排列:
- import sys
- from PyQt5.QtWidgets import (
- QApplication,
- QPushButton,
- QVBoxLayout,
- QWidget,
- )
- class Window(QWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("QVBoxLayout Example")
- self.resize(270, 110)
- # Create a QVBoxLayout instance
- layout = QVBoxLayout()
- # Add widgets to the layout
- layout.addWidget(QPushButton("Top"))
- layout.addWidget(QPushButton("Center"))
- layout.addWidget(QPushButton("Bottom"))
- # 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_())
在第16行上,您將創(chuàng)建QVBoxLayout的實例。在第18至20行上,將三個按鈕添加到布局中。最后,將布局設(shè)置為窗口的頂層布局。
如果您運行此應用程序,則將顯示以下窗口:
您的窗口顯示了三個垂直排列的按鈕,一個在另一個按鈕下面。這些按鈕的顯示順序(從上到下)與您在代碼中添加的順序(從上到下)相同。
在網(wǎng)格中排列小部件:QGridLayout
您可以使用QGridLayout將小部件排列在行和列的網(wǎng)格中。每個小部件將在網(wǎng)格中具有相對位置。要定義小部件的位置或網(wǎng)格中的單元格,請使用表格(行,列)的一對坐標。這些坐標應該是從零開始的整數(shù)。
QGridLayout占用其父級的可用空間,將其劃分為行和列,然后將每個小部件放置在其自己的單元格或框中。QGridLayout根據(jù)小部件的數(shù)量及其坐標自動計算出最終布局將包含多少行和多少列。如果您不將小部件添加到給定的單元格,則QGridLayout將使該單元格為空。
要將小部件添加到網(wǎng)格布局,請在布局上調(diào)用.addWidget()。此方法有兩個不同的重載實現(xiàn):
第一個實現(xiàn)采用以下參數(shù):
這是一個如何使用QGridLayout創(chuàng)建小部件網(wǎng)格的示例:
- import sys
- from PyQt5.QtWidgets import (
- QApplication,
- QGridLayout,
- QPushButton,
- QWidget,
- )
- class Window(QWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("QGridLayout Example")
- # Create a QGridLayout instance
- layout = QGridLayout()
- # Add widgets to the layout
- layout.addWidget(QPushButton("Button at (0, 0)"), 0, 0)
- layout.addWidget(QPushButton("Button at (0, 1)"), 0, 1)
- layout.addWidget(QPushButton("Button at (0, 2)"), 0, 2)
- layout.addWidget(QPushButton("Button at (1, 0)"), 1, 0)
- layout.addWidget(QPushButton("Button at (1, 1)"), 1, 1)
- layout.addWidget(QPushButton("Button at (1, 2)"), 1, 2)
- layout.addWidget(QPushButton("Button at (2, 0)"), 2, 0)
- layout.addWidget(QPushButton("Button at (2, 1)"), 2, 1)
- layout.addWidget(QPushButton("Button at (2, 2)"), 2, 2)
- # 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_())
在第15行上,創(chuàng)建QGridLayout對象。然后,在第17至25行上,使用.addWidget()將小部件添加到布局中。要查看沒有分配小部件的網(wǎng)格布局如何管理單元,請注釋掉其中的一行或多行,然后再次運行應用程序。
如果您從命令行運行此代碼,則將獲得如下所示的窗口:
QGridLayout對象中的每個小部件都占據(jù)由您在.addWidget()中提供的一對坐標定義的單元格。每個按鈕上的文字均反映了這些坐標。坐標是從零開始的,因此第一個單元格位于(0,0)。
在.addWidget()的第二種實現(xiàn)中,widget和alignment參數(shù)保持不變,并且您還有四個其他參數(shù)可用于將小部件放置在多行或多列中:
這是一個顯示.addWidget()變體如何工作的應用程序:
- import sys
- from PyQt5.QtWidgets import (
- QApplication,
- QGridLayout,
- QPushButton,
- QWidget,
- )
- class Window(QWidget):
- def __init__(self):
- super().__init__()
- self.setWindowTitle("QGridLayout Example")
- # Create a QGridLayout instance
- layout = QGridLayout()
- # Add widgets to the layout
- layout.addWidget(QPushButton("Button at (0, 0)"), 0, 0)
- layout.addWidget(QPushButton("Button at (0, 1)"), 0, 1)
- layout.addWidget(QPushButton("Button Spans two Cols"), 1, 0, 1, 2)
- # 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_())
在第19行,使用.addWidget()的第二種實現(xiàn)來添加一個占用網(wǎng)格中兩列的按鈕。該按鈕從第二行(fromRow = 1)和第一列(fromColumn = 0)開始。最后,該按鈕占據(jù)一行(rowSpan = 1)和兩列(columnSpan = 2)。
如果您運行此應用程序,則會在屏幕上看到以下窗口:
在這種布局中,您可以使一個小部件占用多個單元格,就像使用“跨越兩個列”的按鈕一樣。
在下篇中,我們將看到:

我們在微信上24小時期待你的聲音
解答本文疑問/技術(shù)咨詢/運營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流