Layout 布局 ( 垂直水平 )
这篇教学会介绍如何透过 PyQt5 视窗里的 QVBoxLayout() 和 QHBoxLayout() 方法,进行元件的垂直与水平布局。
快速导览:
- PyQt6 版本参考:PyQt6 教学 - Layout 布局 ( 垂直与水平 )
- 因为 Google Colab 不支援 PyQt5,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。
建立 Layout 垂直与水平布局
当 PyQt5 建立视窗后,视窗本身是一个 Widget,因此只要使用 QVBoxLayout() 和 QHBoxLayout() 方法,就可以在视窗 Widget 上建立垂直或水平布局的“layout”,当 layout 建立后,只要放在该 layout 里的元件,就会按照布局的位置排列,无法透过 move() 或 setGeometry() 方法设定位置与大小。
下方的程序码执行后,会在画面左边建立一个垂直 Layout,放入三颗按钮,在画面右边建立一个水平 Layout,也放入三颗按钮,在不做任何设定的状况下,按钮就会根据 Layout 的规范进行排列。
from PyQt5 import QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
# 垂直 Layout
vbox = QtWidgets.QWidget(Form) # 建立一個新的 Widget
vbox.setGeometry(0,0,150,150) # 設定 Widget 大小
v_layout = QtWidgets.QVBoxLayout(vbox) # 建立垂直 Layout
btn1 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn1.setText('1') # 按鈕文字
v_layout.addWidget(btn1) # 將按鈕放入 v_layout 中
btn2 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn2.setText('2') # 按鈕文字
v_layout.addWidget(btn2) # 將按鈕放入 v_layout 中
btn3 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn3.setText('3') # 按鈕文字
v_layout.addWidget(btn3) # 將按鈕放入 v_layout 中
# 水平 Layout
hbox = QtWidgets.QWidget(Form) # 建立一個新的 Widget
hbox.setGeometry(150,0,150,150) # 設定 Widget 大小
h_layout = QtWidgets.QHBoxLayout(hbox) # 建立水平 Layout
btn4 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn4.setText('4') # 按鈕文字
h_layout.addWidget(btn4) # 將按鈕放入 h_layout 中
btn5 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn5.setText('5') # 按鈕文字
h_layout.addWidget(btn5) # 將按鈕放入 h_layout 中
btn6 = QtWidgets.QPushButton(Form) # 在視窗中加入一個 QPushButton
btn6.setText('6') # 按鈕文字
h_layout.addWidget(btn6) # 將按鈕放入 h_layout 中
Form.show()
sys.exit(app.exec_())
设定 Layout 里元件的对齐方式
Layout 加入元件后,可以透过下列几种对齐方法,设定元件的对齐方式:
| 对齐方式 | 说明 |
|---|---|
| QtCore.Qt.AlignTop | 靠上对齐。 |
| QtCore.Qt.AlignBottom | 靠下对齐。 |
| QtCore.Qt.AlignCenter | 置中对齐。 |
| QtCore.Qt.AlignLeft | 靠左对齐。 |
| QtCore.Qt.AlignRight | 靠右对齐。 |
| QtCore.Qt.AlignVCenter | 垂直置中对齐。 |
| QtCore.Qt.AlignHCenter | 水平置中对齐。 |
下方的程序码执行后,会将左侧垂直排列的按钮靠左对齐,将右侧水平排列的按钮靠上对齐。
from PyQt5 import QtWidgets, QtCore
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
# 垂直 Layout
vbox = QtWidgets.QWidget(Form)
vbox.setGeometry(0,0,150,150)
v_layout = QtWidgets.QVBoxLayout(vbox)
v_layout.setAlignment(QtCore.Qt.AlignLeft) # 靠左對齊
btn1 = QtWidgets.QPushButton(Form)
btn1.setText('1')
v_layout.addWidget(btn1)
btn2 = QtWidgets.QPushButton(Form)
btn2.setText('2')
v_layout.addWidget(btn2)
btn3 = QtWidgets.QPushButton(Form)
btn3.setText('3')
v_layout.addWidget(btn3)
# 水平 Layout
hbox = QtWidgets.QWidget(Form)
hbox.setGeometry(150,0,150,150)
h_layout = QtWidgets.QHBoxLayout(hbox)
h_layout.setAlignment(QtCore.Qt.AlignTop) # 靠上對齊
btn4 = QtWidgets.QPushButton(Form)
btn4.setText('4')
h_layout.addWidget(btn4)
btn5 = QtWidgets.QPushButton(Form)
btn5.setText('5')
h_layout.addWidget(btn5)
btn6 = QtWidgets.QPushButton(Form)
btn6.setText('6')
h_layout.addWidget(btn6)
Form.show()
sys.exit(app.exec_())
调整 Layout 样式
建立放置 Layout 的 Widget 后,可以针对这个 Widget 使用 setStyleSheet() 方法设定样式,但需要注意的是,一但设定这个 Widget 样式,会连带影响到里头的元件样式,因此如果需要设定样式,要连同里面的元件一并进行设定,以下方的程序码为例,将放置 Layout 的 Widget 设定为白底黑框后,需要额外设定按钮的样式,否则按钮的默认样式就会消失。
from PyQt5 import QtWidgets, QtCore
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
Form.setWindowTitle('oxxo.studio')
Form.resize(300, 200)
# 設定放置 Layout 的 Widget 樣式
style_box = '''
background:#fff;
border:1px solid #000;
'''
# 設定按鈕樣式
style_btn = '''
QPushButton{
background:#ff0;
border:1px solid #000;
border-radius:10px;
padding:5px;
}
QPushButton:pressed{
background:#f90;
}
'''
# 垂直 Layout
vbox = QtWidgets.QWidget(Form)
vbox.setGeometry(0,0,120,120)
vbox.setStyleSheet(style_box)
v_layout = QtWidgets.QVBoxLayout(vbox)
v_layout.setAlignment(QtCore.Qt.AlignLeft) # 靠左對齊
btn1 = QtWidgets.QPushButton(Form)
btn1.setText('1')
btn1.setStyleSheet(style_btn)
v_layout.addWidget(btn1)
btn2 = QtWidgets.QPushButton(Form)
btn2.setText('2')
btn2.setStyleSheet(style_btn)
v_layout.addWidget(btn2)
btn3 = QtWidgets.QPushButton(Form)
btn3.setText('3')
btn3.setStyleSheet(style_btn)
v_layout.addWidget(btn3)
# 水平 Layout
hbox = QtWidgets.QWidget(Form)
hbox.setGeometry(130,0,120,120)
hbox.setStyleSheet(style_box)
h_layout = QtWidgets.QHBoxLayout(hbox)
h_layout.setAlignment(QtCore.Qt.AlignTop) # 靠上對齊
btn4 = QtWidgets.QPushButton(Form)
btn4.setText('4')
btn4.setStyleSheet(style_btn)
h_layout.addWidget(btn4)
btn5 = QtWidgets.QPushButton(Form)
btn5.setText('5')
btn5.setStyleSheet(style_btn)
h_layout.addWidget(btn5)
btn6 = QtWidgets.QPushButton(Form)
btn6.setText('6')
btn6.setStyleSheet(style_btn)
h_layout.addWidget(btn6)
Form.show()
sys.exit(app.exec_())
改用 class 的写法
上方的程序码,亦可改用 class 的写法表示。
from PyQt5 import QtWidgets, QtCore
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.style()
self.ui_v()
self.ui_h()
def style(self):
self.style_box = '''
background:#fff;
border:1px solid #000;
'''
self.style_btn = '''
QPushButton{
background:#ff0;
border:1px solid #000;
border-radius:10px;
padding:5px;
}
QPushButton:pressed{
background:#f90;
}
'''
def ui_v(self):
self.vbox = QtWidgets.QWidget(self)
self.vbox.setGeometry(0,0,120,120)
self.vbox.setStyleSheet(self.style_box)
self.v_layout = QtWidgets.QVBoxLayout(self.vbox)
self.v_layout.setAlignment(QtCore.Qt.AlignLeft) # 靠左對齊
self.btn1 = QtWidgets.QPushButton(self)
self.btn1.setText('1')
self.btn1.setStyleSheet(self.style_btn)
self.v_layout.addWidget(self.btn1)
self.btn2 = QtWidgets.QPushButton(self)
self.btn2.setText('2')
self.btn2.setStyleSheet(self.style_btn)
self.v_layout.addWidget(self.btn2)
self.btn3 = QtWidgets.QPushButton(self)
self.btn3.setText('3')
self.btn3.setStyleSheet(self.style_btn)
self.v_layout.addWidget(self.btn3)
def ui_h(self):
self.hbox = QtWidgets.QWidget(self)
self.hbox.setGeometry(130,0,120,120)
self.hbox.setStyleSheet(self.style_box)
self.h_layout = QtWidgets.QHBoxLayout(self.hbox)
self.h_layout.setAlignment(QtCore.Qt.AlignTop) # 靠上對齊
self.btn4 = QtWidgets.QPushButton(self)
self.btn4.setText('4')
self.btn4.setStyleSheet(self.style_btn)
self.h_layout.addWidget(self.btn4)
self.btn5 = QtWidgets.QPushButton(self)
self.btn5.setText('5')
self.btn5.setStyleSheet(self.style_btn)
self.h_layout.addWidget(self.btn5)
self.btn6 = QtWidgets.QPushButton(self)
self.btn6.setText('6')
self.btn6.setStyleSheet(self.style_btn)
self.h_layout.addWidget(self.btn6)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec_())
微信扫码关注
抖音扫码关注