PyQt5教程(三)——佈局管理

原文:http://zetcode.com/gui/pyqt5/layout/python

佈局管理是GUI編程中的重要部分。佈局管理是如何將控件放置於窗體上的技術,它的實現有兩種基本方式:絕對佈局與layout類。程序員

##絕對佈局web

程序員要指定每一個控件的像素位置與大小。在使用絕對佈局時要知道它的侷限:編程

  • 控件的尺寸與位置不會隨着窗體尺寸的調整而變化
  • 程序在不一樣平臺上可能會有不一樣的外觀
  • 改變程序的字體可能會破壞佈局
  • 若是想改變佈局,只能重作,這很無聊並且很費時

下面的示例中以絕對座標來放置控件。app

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

This example shows three labels on a window
using absolute positioning. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import QWidget, QLabel, QApplication


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        lbl1 = QLabel('Zetcode', self)
        lbl1.move(15, 10)

        lbl2 = QLabel('tutorials', self)
        lbl2.move(35, 40)
        
        lbl3 = QLabel('for programmers', self)
        lbl3.move(55, 70)        
        
        self.setGeometry(300, 300, 250, 150)
        self.setWindowTitle('Absolute')    
        self.show()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

咱們使用move()方法來放置控件。在例子中咱們經過設置x、y座標來放置label。座標系統的原點位於窗體左上角。x軸從左到右增加,y軸從上到下增加。佈局

lbl1 = QLabel('Zetcode', self)
lbl1.move(15, 10)

label控件位於x=15,y=10的座標上。字體

Absolute positioning

Box layout

佈局類提供的佈局管理具備更好的靈活性與實用性,它是在窗體上放置控件的首選方式。QHBoxLayoutQVBoxLayout是水平與垂直放置控件的兩個基本佈局類。ui

假如要在右下角放置兩個按鈕,咱們要藉助於HBoxLayout與VBoxLayout,並設置stretch factor(伸展係數)來建立所需的空白空間。this

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we position two push
buttons in the bottom-right corner 
of the window. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import (QWidget, QPushButton, 
    QHBoxLayout, QVBoxLayout, QApplication)


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        okButton = QPushButton("OK")
        cancelButton = QPushButton("Cancel")

        hbox = QHBoxLayout()
        hbox.addStretch(1)
        hbox.addWidget(okButton)
        hbox.addWidget(cancelButton)

        vbox = QVBoxLayout()
        vbox.addStretch(1)
        vbox.addLayout(hbox)
        
        self.setLayout(vbox)    
        
        self.setGeometry(300, 300, 300, 150)
        self.setWindowTitle('Buttons')    
        self.show()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

這個示例在窗體的右下角放置了兩個按鈕。當調整窗體尺寸時它們的位置不會改變。咱們同時用到了QHBoxLayoutQVBoxLayoutcode

okButton = QPushButton("OK")
cancelButton = QPushButton("Cancel")

這裏建立了兩個按鈕

hbox = QHBoxLayout()
hbox.addStretch(1)
hbox.addWidget(okButton)
hbox.addWidget(cancelButton)

咱們建立了一個水平boxlayout並添加了一個伸展係數和兩個按鈕。stretch方法會在兩按鈕前面添加一個伸展空間,從而將按鈕擠到窗體的右側。

vbox = QVBoxLayout()
vbox.addStretch(1)
vbox.addLayout(hbox)

經過將水平佈局置於垂直佈局內來獲得咱們須要的佈局。垂直佈局的伸展係數會將按鈕擠到窗體底部。

self.setLayout(vbox)

最後將vbox設爲窗體的主佈局。

Buttons

QGridLayout

網格佈局是最經常使用的佈局。它會按行列對空間進行切分。咱們使用類QGridLayout建立網格佈局。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we create a skeleton
of a calculator using a QGridLayout.

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import (QWidget, QGridLayout, 
    QPushButton, QApplication)


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        grid = QGridLayout()
        self.setLayout(grid)
 
        names = ['Cls', 'Bck', '', 'Close',
                 '7', '8', '9', '/',
                '4', '5', '6', '*',
                 '1', '2', '3', '-',
                '0', '.', '=', '+']
        
        positions = [(i,j) for i in range(5) for j in range(4)]
        
        for position, name in zip(positions, names):
            
            if name == '':
                continue
            button = QPushButton(name)
            grid.addWidget(button, *position)
            
        self.move(300, 150)
        self.setWindowTitle('Calculator')
        self.show()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

在這個例子中咱們建立填滿整個網格的按鈕。

grid = QGridLayout()
self.setLayout(grid)

這裏建立了一個QGridLayout實例,並將它設爲窗體的佈局。

names = ['Cls', 'Bck', '', 'Close',
            '7', '8', '9', '/',
        '4', '5', '6', '*',
            '1', '2', '3', '-',
        '0', '.', '=', '+']

這些是按鈕的標籤。

positions = [(i,j) for i in range(5) for j in range(4)]

咱們在網格中建立了一系列位置座標。

for position, name in zip(positions, names):
    
    if name == '':
        continue
    button = QPushButton(name)
    grid.addWidget(button, *position)

經過addWidget()方法將建立的按鈕添加到佈局中。

Calculator Skeleton

一個簡單的評論窗體

控件能夠在佈局中跨行或跨列。正以下面的例子所展現的。

#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
ZetCode PyQt5 tutorial 

In this example, we create a bit
more complicated window layout using
the QGridLayout manager. 

author: Jan Bodnar
website: zetcode.com 
last edited: January 2015
"""

import sys
from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, 
    QTextEdit, QGridLayout, QApplication)


class Example(QWidget):
    
    def __init__(self):
        super().__init__()
        
        self.initUI()
        
        
    def initUI(self):
        
        title = QLabel('Title')
        author = QLabel('Author')
        review = QLabel('Review')

        titleEdit = QLineEdit()
        authorEdit = QLineEdit()
        reviewEdit = QTextEdit()

        grid = QGridLayout()
        grid.setSpacing(10)

        grid.addWidget(title, 1, 0)
        grid.addWidget(titleEdit, 1, 1)

        grid.addWidget(author, 2, 0)
        grid.addWidget(authorEdit, 2, 1)

        grid.addWidget(review, 3, 0)
        grid.addWidget(reviewEdit, 3, 1, 5, 1)
        
        self.setLayout(grid) 
        
        self.setGeometry(300, 300, 350, 300)
        self.setWindowTitle('Review')    
        self.show()
        
        
if __name__ == '__main__':
    
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

咱們建立了一個帶有三個Label、兩個LineEdit和一個TextEdit的窗體。採用了QGridLayout佈局。

grid = QGridLayout()
grid.setSpacing(10)

咱們建立了一個網格佈局併爲它設置了控件間距。

grid.addWidget(reviewEdit, 3, 1, 5, 1)

在添加控件的時候咱們能夠設置控件跨行或跨列。在例子中咱們將reviewEdit控件跨越5行。

Review example

這部分教程主要講解了佈局管理。

相關文章
相關標籤/搜索