新聞中心
PyQt的布局管理器layout managers提供了一種用戶友好且高效的方式,可以在GUI上排列圖形組件或小部件。正確布置窗口小部件將使您的GUI應(yīng)用程序看起來更加優(yōu)美和專業(yè)。學(xué)習(xí)有效地做到這一點(diǎn)是您使用Python和PyQt進(jìn)行GUI應(yīng)用程序開發(fā)和運(yùn)行的一項(xiàng)基本技能。

成都創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè),為客戶提供成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)開發(fā)服務(wù),多年建網(wǎng)站服務(wù)經(jīng)驗(yàn),各類網(wǎng)站都可以開發(fā),品牌網(wǎng)站建設(shè),公司官網(wǎng),公司展示網(wǎng)站,網(wǎng)站設(shè)計(jì),建網(wǎng)站費(fèi)用,建網(wǎng)站多少錢,價(jià)格優(yōu)惠,收費(fèi)合理。
在本教程中,您將學(xué)習(xí):
- 使用PyQt的layout managers有什么好處
- 如何使用PyQt的layout managers在GUI上以編程方式布置窗口小部件
- 如何為您的GUI應(yīng)用程序選擇正確的layout manager
- 如何在基于主窗口和基于對(duì)話框的應(yīng)用程序中布置小部件
有了這些知識(shí)和技能,您就可以使用Python和PyQt創(chuàng)建具有專業(yè)外觀的GUI應(yīng)用程序。
在GUI上布置圖形元素
在創(chuàng)建圖形用戶界面(GUI)應(yīng)用程序時(shí),一個(gè)常見的問題是如何使圖形組件(按鈕,菜單,工具欄,標(biāo)簽等)一致地放置在窗體和窗口上。此過程稱為GUI布局(GUI layout,),這是創(chuàng)建GUI應(yīng)用程序的重要步驟。
之前如果要在窗口上布置圖形組件或窗口小部件,則可以采用以下方法之一:
- 為窗口上的每個(gè)小部件確定并手動(dòng)設(shè)置靜態(tài)大小和位置。
- 動(dòng)態(tài)計(jì)算并設(shè)置每個(gè)小部件的大小和位置。
第一種方法相當(dāng)直接,但是至少具有以下缺點(diǎn):
- 您的窗口將無法調(diào)整大小,以不同的屏幕分辨率顯示它們時(shí)可能會(huì)導(dǎo)致問題。
- 您的標(biāo)簽可能不能正確地支持本地化,因?yàn)榻o定文本的長(zhǎng)度在不同語(yǔ)言之間會(huì)發(fā)生變化。
- 您的窗口小部件在不同平臺(tái)上的顯示方式將有所不同,這使得編寫看起來不錯(cuò)的多平臺(tái)應(yīng)用程序變得困難。
第二種方法更靈活。但是,它也有缺點(diǎn):
- 您必須進(jìn)行大量手動(dòng)計(jì)算才能確定每個(gè)小部件的正確大小和位置。
- 您必須做一些額外的計(jì)算才能正確響應(yīng)窗口大小調(diào)整。
- 每當(dāng)您修改窗口布局時(shí),都必須重做所有計(jì)算。
即使您仍然可以使用這兩種方法中的任何一種來布局GUI,大多數(shù)時(shí)候您可能還是希望使用由最先進(jìn)的GUI框架或工具包實(shí)現(xiàn)的第三種且更方便的方法:布局管理器layout managers。注意:在某些GUI框架(例如Tkinter)中,布局管理器也稱為geometry managers。
layout managers會(huì)根據(jù)您的特定需求自動(dòng)在GUI上排列小 部件。它避免了第一種方法的兼容性缺點(diǎn)以及第二種方法的復(fù)雜計(jì)算。
在以下各節(jié)中,您將了解PyQt的內(nèi)置布局管理器以及如何使用它們有效地布局GUI應(yīng)用程序的圖形組件。
多樣的PyQt布局形式
在PyQt中,小部件是用作GUI應(yīng)用程序構(gòu)建塊的圖形組件。將一堆小部件放在窗口上以創(chuàng)建GUI時(shí),需要給它們一些順序。您需要設(shè)置窗口小部件的大小和在窗口上的位置,還需要定義當(dāng)用戶調(diào)整基礎(chǔ)窗口大小時(shí)它們的行為。
注意:PyQt5的官方文檔中有一些不完整的部分。要解決此問題,您可以查看PyQt4文檔,Qt for Python文檔或原始Qt文檔。
要在PyQt的窗口或窗體上排列小部件,可以使用以下技術(shù):
- 在小部件上使用.resize()和.move()來提供絕對(duì)大小和位置。
- 重新實(shí)現(xiàn).resizeEvent()并動(dòng)態(tài)計(jì)算小部件的大小和位置。
- 使用布局管理器,讓他們?yōu)槟鏊械挠?jì)算和辛苦的工作。
這些技術(shù)通常對(duì)應(yīng)于上一節(jié)中介紹的用于布局GUI的三種不同方法。
再說一次,動(dòng)態(tài)計(jì)算尺寸和位置可能是個(gè)好方法,但是大多數(shù)時(shí)候,使用布局管理器會(huì)更好。在PyQt中,布局管理器是提供所需功能以自動(dòng)管理布局中小部件的大小,位置和調(diào)整大小行為的類。
使用布局管理器,您可以自動(dòng)在任何母部件、容器、小部件內(nèi)排列子部件。使用布局管理器將確保您充分利用GUI上的可用空間,并確保當(dāng)用戶調(diào)整窗口大小時(shí),應(yīng)用程序仍然可用。
布局管理器充當(dāng)小部件和其他布局的容器時(shí),要將小部件添加到布局管理器,請(qǐng)?jiān)诋?dāng)前布局上調(diào)用.addWidget()。要將布局添加到另一個(gè)布局,請(qǐng)?jiān)诋?dāng)前布局上調(diào)用.addLayout()。您將在“嵌套布局以構(gòu)建復(fù)雜的GUI”一節(jié)中更深入地了解嵌套布局。
將所有必需的小部件添加到布局管理器后,即可使用.setLayout()在給定的小部件上設(shè)置布局管理器。您可以在QWidget的任何子類(包括窗口或窗體)上設(shè)置布局管理器。
注意:QMainWindow是一個(gè)PyQt類,可用于創(chuàng)建main widow–style applications.。此類具有其自己的內(nèi)置布局管理器。因此,如果您使用的是QMainWindow,則通常不需要在主窗口對(duì)象上設(shè)置布局管理器。
布局中的所有窗口小部件都會(huì)自動(dòng)設(shè)置為安裝布局的窗口小部件的子級(jí),而不是布局本身。這是因?yàn)榇翱谛〔考荒軐⑵渌翱谛〔考ǘ皇遣季郑┳鳛槠涓讣?jí)。
PyQt的布局管理器提供了一些很酷的功能,可以使您在創(chuàng)建美觀的GUI應(yīng)用程序時(shí)更加輕松:
- 處理小部件的大小和位置,無需任何計(jì)算
- 當(dāng)用戶調(diào)整基礎(chǔ)窗口的大小時(shí),處理窗口小部件的大小調(diào)整和重新定位
- 調(diào)整標(biāo)簽大小以更好地支持國(guó)際化
- 為多平臺(tái)應(yīng)用程序提供本機(jī)窗口布局
從長(zhǎng)遠(yuǎn)來看,使用布局管理器還將極大地提高您的生產(chǎn)率并改善代碼的可維護(hù)性。
PyQt提供了四個(gè)通用布局管理器類:
- QHBoxLayout在水平框中排列小部件。
- QVBoxLayout在垂直框中排列小部件。
- QGridLayout將小部件排列在網(wǎng)格中。
- QFormLayout將小部件安排在兩列中。
在接下來的幾節(jié)中,您將學(xué)習(xí)如何使用這些通用布局管理器的基礎(chǔ)知識(shí)。
使用通用布局管理器
使用PyQt創(chuàng)建GUI應(yīng)用程序時(shí),通常會(huì)使用上一節(jié)末尾看到的四種通用布局中的一種或多種方法,來將窗口小部件布置在窗口和窗體上。
在接下來的幾節(jié)中,您將在一些示例的幫助下學(xué)習(xí)如何創(chuàng)建和使用四個(gè)通用布局管理器。
構(gòu)建水平布局:QHBoxLayout
Box layout managers從父布局或窗口小部件獲得的空間被分成多個(gè)盒子或單元格,然后使布局中的每個(gè)窗口小部件填充一個(gè)盒子。
QHBoxLayout是PyQt中兩個(gè)可用的框布局之一。這個(gè)布局管理器允許您水平排列小部件,一個(gè)接一個(gè)。這些小部件從左到右添加到布局中。這意味著您首先在代碼中添加的小部件將是布局中最左側(cè)的小部件。
要將小部件添加到QHBoxLayout對(duì)象,請(qǐng)?jiān)诓季謱?duì)象上調(diào)用.addWidget(widget,stretch,alignment)。此方法接受一個(gè)必需參數(shù)和兩個(gè)可選參數(shù):
- widget是必填參數(shù),用于保存要添加到布局的特定widget。
- Stretch是一個(gè)可選參數(shù),其中包含一個(gè)整數(shù),該整數(shù)表示要應(yīng)用于小部件的拉伸因子。具有較高拉伸因子的小部件在調(diào)整窗口大小時(shí)會(huì)增長(zhǎng)更多。默認(rèn)為0,這表示未分配窗口小部件拉伸因子。
- alignment是一個(gè)可選參數(shù),其中包含水平和垂直標(biāo)志。您可以組合這些標(biāo)志,以在其包含的單元格內(nèi)產(chǎn)生所需的小部件對(duì)齊方式。默認(rèn)為0,這意味著小部件將填充整個(gè)單元格。
下面是一個(gè)小型應(yīng)用程序,顯示了如何使用QHBoxLayout創(chuàng)建水平布局。在此示例中,您將使用QPushButton對(duì)象根據(jù)將小部件添加到代碼中的順序更好地可視化每個(gè)小部件在布局中的放置位置:
- 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)建一個(gè)稱為layout的QHBoxLayout對(duì)象。在第17至19行,使用.addWidget()將三個(gè)按鈕添加到布局中。請(qǐng)注意,您分別在“居中”和“最右”按鈕中將1和2傳遞給了stretch參數(shù)。在第21行,使用.setLayout()將布局設(shè)置為窗口的頂級(jí)布局。
如果您運(yùn)行此應(yīng)用程序,則會(huì)在屏幕上看到以下窗口:
該窗口包含三個(gè)水平排列的按鈕。請(qǐng)注意,“最左鍵”按鈕對(duì)應(yīng)于您在代碼中添加的第一個(gè)按鈕。因此,按鈕的顯示順序與您在代碼中添加按鈕的順序(從左到右)(從上到下)相同。
“居中”和“最右邊”按鈕具有不同的拉伸系數(shù),因此在調(diào)整窗口大小時(shí),它們會(huì)按比例縮放。
此外,布局中的所有按鈕和布局本身都設(shè)置為Window的子級(jí)。這是由布局對(duì)象自動(dòng)完成的,該布局對(duì)象在每個(gè)小部件上內(nèi)部調(diào)用.setParent()。在第17行上對(duì)print()的調(diào)用將在您的終端上打印Window的子代列表,以證明此行為。
構(gòu)建垂直布局:QVBoxLayout
QVBoxLayout垂直排列小部件,一個(gè)在另一個(gè)下方。您可以使用此類創(chuàng)建垂直布局,并從上到下排列窗口小部件。由于QVBoxLayout是另一個(gè)框布局,因此其.addWidget()方法的工作方式與QHBoxLayout中的相同。
下面是一個(gè)PyQt應(yīng)用程序,它顯示了如何創(chuàng)建和使用QVBoxLayout對(duì)象在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的實(shí)例。在第18至20行上,將三個(gè)按鈕添加到布局中。最后,將布局設(shè)置為窗口的頂層布局。
如果您運(yùn)行此應(yīng)用程序,則將顯示以下窗口:
您的窗口顯示了三個(gè)垂直排列的按鈕,一個(gè)在另一個(gè)按鈕下面。這些按鈕的顯示順序(從上到下)與您在代碼中添加的順序(從上到下)相同。
在網(wǎng)格中排列小部件:QGridLayout
您可以使用QGridLayout將小部件排列在行和列的網(wǎng)格中。每個(gè)小部件將在網(wǎng)格中具有相對(duì)位置。要定義小部件的位置或網(wǎng)格中的單元格,請(qǐng)使用表格(行,列)的一對(duì)坐標(biāo)。這些坐標(biāo)應(yīng)該是從零開始的整數(shù)。
QGridLayout占用其父級(jí)的可用空間,將其劃分為行和列,然后將每個(gè)小部件放置在其自己的單元格或框中。QGridLayout根據(jù)小部件的數(shù)量及其坐標(biāo)自動(dòng)計(jì)算出最終布局將包含多少行和多少列。如果您不將小部件添加到給定的單元格,則QGridLayout將使該單元格為空。
要將小部件添加到網(wǎng)格布局,請(qǐng)?jiān)诓季稚险{(diào)用.addWidget()。此方法有兩個(gè)不同的重載實(shí)現(xiàn):
- addWidget(widget, row, column, alignment)將widget添加到(row, column)的單元格中。
- addWidget(widget,fromRow,fromColumn,rowSpan,columnSpan,alignment)將widget添加到單元格中,跨越多行,多列或兩者。
第一個(gè)實(shí)現(xiàn)采用以下參數(shù):
- widget是必填參數(shù),用于保存您需要添加到布局的特定小部件。
- row是必填參數(shù),其中包含一個(gè)整數(shù),該整數(shù)表示網(wǎng)格中行的坐標(biāo)。
- column是必填參數(shù),其中包含一個(gè)整數(shù),該整數(shù)表示網(wǎng)格中列的坐標(biāo)。
- alignment是一個(gè)可選參數(shù),用于保存小部件在其包含的單元格內(nèi)的對(duì)齊方式。默認(rèn)為0,這意味著小部件將填充整個(gè)單元格。
這是一個(gè)如何使用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對(duì)象。然后,在第17至25行上,使用.addWidget()將小部件添加到布局中。要查看沒有分配小部件的網(wǎng)格布局如何管理單元,請(qǐng)注釋掉其中的一行或多行,然后再次運(yùn)行應(yīng)用程序。
如果您從命令行運(yùn)行此代碼,則將獲得如下所示的窗口:
QGridLayout對(duì)象中的每個(gè)小部件都占據(jù)由您在.addWidget()中提供的一對(duì)坐標(biāo)定義的單元格。每個(gè)按鈕上的文字均反映了這些坐標(biāo)。坐標(biāo)是從零開始的,因此第一個(gè)單元格位于(0,0)。
在.addWidget()的第二種實(shí)現(xiàn)中,widget和alignment參數(shù)保持不變,并且您還有四個(gè)其他參數(shù)可用于將小部件放置在多行或多列中:
- fromRow賦值一個(gè)整數(shù),該整數(shù)表示小部件將在其中開始的行。
- fromColumn賦值一個(gè)整數(shù),該整數(shù)表示小部件將在其中開始的列。
- rowSpan賦值一個(gè)整數(shù),該整數(shù)表示窗口小部件將在網(wǎng)格中占據(jù)的行數(shù)。
- columnSpan賦值一個(gè)整數(shù),該整數(shù)表示窗口小部件將在網(wǎng)格中占據(jù)的列數(shù)。
這是一個(gè)顯示.addWidget()變體如何工作的應(yī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 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()的第二種實(shí)現(xiàn)來添加一個(gè)占用網(wǎng)格中兩列的按鈕。該按鈕從第二行(fromRow = 1)和第一列(fromColumn = 0)開始。最后,該按鈕占據(jù)一行(rowSpan = 1)和兩列(columnSpan = 2)。
如果您運(yùn)行此應(yīng)用程序,則會(huì)在屏幕上看到以下窗口:
在這種布局中,您可以使一個(gè)小部件占用多個(gè)單元格,就像使用“跨越兩個(gè)列”的按鈕一樣。
在下篇中,我們將看到:
- 如何快速創(chuàng)建表單
- 嵌套布局以構(gòu)建復(fù)雜的GUI
- 使用多頁(yè)布局和小部件
- 布置應(yīng)用程序的主窗口
- 布置應(yīng)用程序的對(duì)話框
- 在PyQt布局中管理輸入框
網(wǎng)站題目:用PyQt打造具有專業(yè)外觀的GUI(上)
標(biāo)題來源:http://m.fisionsoft.com.cn/article/dhsehes.html


咨詢
建站咨詢
