
繼承圖:

在布局中添加控件用addWidght(),添加布局用addLayout()
QBoxLayout:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QBoxLayout from PyQt5.QtCore import QSize class Label(QLabel): def minimumSizeHint(self): #建議的最小尺寸函數 return QSize(50,50) class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,300) self.label1 = Label('標簽1') self.label2 = QLabel('標簽2') self.label3 = QLabel('標簽3') self.label1.setStyleSheet('background-color: rgb(255, 0, 0)') self.label2.setStyleSheet('background-color: rgb(0, 255, 0)') self.label3.setStyleSheet('background-color: rgb(0, 0, 255)') layout=QBoxLayout(QBoxLayout.RightToLeft) #創建一個盒子布局 #參數1 布局方向: --必須有 #QBoxLayout.TopToBottom=2 從上往下 #QBoxLayout.BottomToTop=3 從下往上 #QBoxLayout.LeftToRight=0 從左往右 #QBoxLayout.RightToLeft=1 從右往左 self.setLayout(layout) #給self設置布局管理器 layout.addWidget(self.label1) #給布局管理器添加控件 # 這是QLayout的指令 #layout.addSpacing(50) #添加間距-間距 #參數 像素 layout.addWidget(self.label2) layout.addWidget(self.label3) layout.setSpacing(2) #設置內邊距---控件之間的距離 #這是QLayout的指令 layout.setContentsMargins(20,30,40,50) #設置外邊距--控件到窗口邊框的距離 # 這是QLayout的指令 # 參數1 左邊距離 # 參數2 上邊距離 # 參數3 右邊距離 # 參數4 下邊距離 self.label4 = QLabel('標簽4') self.label4.setStyleSheet('background-color: yellow') layout.replaceWidget(self.label2,self.label4) #替換控件 #把self.label2替換成self.label4 #注意:被替換掉的控件不在受布局管理器的控制,要把它隱藏或刪除或脫離或添加到別的布局管理器中 # 這是QLayout的指令 #self.label2.hide() #隱藏控件 self.label2.setParent(None) #脫離父對象 #布局的嵌套: self.label5 = QLabel('標簽5') self.label5.setStyleSheet('background-color: rgb(255, 255, 0)') self.label6 = QLabel('標簽6') self.label6.setStyleSheet('background-color: rgb(255, 0, 255)') self.label7 = QLabel('標簽7') self.label7.setStyleSheet('background-color: rgb(0, 255, 255)') layout1=QBoxLayout(QBoxLayout.BottomToTop) layout1.addWidget(self.label5) layout1.addWidget(self.label6) layout1.addWidget(self.label7) #layout.addLayout(layout1) #添加布局管理器 # 這是QLayout的指令 layout.setDirection(QBoxLayout.LeftToRight) # 設置方向 # direction() 返回方向 layout.insertWidget(3,self.label2) #插入控件 #參數1 位置序號 layout.insertLayout(2,layout1) #插入布局 # 參數1 位置序號 #layout.removeWidget(self.label1) #從布局中移除控件 #不是刪除控件 layout.insertSpacing(4,50) #插入空白-間距 #參數1 位置索引--不包括已有空白 #參數2 空白像素 layout.setEnabled(True) #是否可用 #默認 True if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QBoxLayout class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,300) self.label1 = QLabel('標簽1') self.label2 = QLabel('標簽2') self.label3 = QLabel('標簽3') self.label1.setStyleSheet('background-color: rgb(255, 0, 0)') self.label2.setStyleSheet('background-color: rgb(0, 255, 0)') self.label3.setStyleSheet('background-color: rgb(0, 0, 255)') layout=QBoxLayout(QBoxLayout.RightToLeft) self.setLayout(layout) # layout.addWidget(self.label1,1) # layout.addWidget(self.label2,2) # layout.addWidget(self.label3,3) #參數2 伸縮因子:就是占用的份數(倍數);總的分成6份,label1占1份,label2占2份,label3占3份 # 0 不伸縮 # layout.addWidget(self.label1, 1) # #layout.addStretch(2) #添加空白伸縮因子 # #注意:這個空白伸縮可以壓縮成0;只有足夠大時才有效 # layout.addWidget(self.label2, 2) # layout.addWidget(self.label3, 3) # # layout.insertStretch(1,2) #插入空白伸縮因子 # #參數1 位置序號 參數2 伸縮份數 layout.addWidget(self.label1) layout.addStretch() layout.addWidget(self.label2) layout.addStretch() layout.addWidget(self.label3) #此時的伸縮因子都是0,控件不在伸縮,會把多余部分都給空白 layout.setStretchFactor(self.label2,1) #設置伸縮因子 #參數1 可以是控件 可以是子布局 layout.setStretchFactor(self.label1, 1) if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
垂直布局QVBoxLayout
需要導入 from PyQt5.QtWidgets import QVBoxLayout
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout from PyQt5.QtCore import Qt class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.label1 = QLabel('標簽1') self.label2 = QLabel('標簽2') self.label3 = QLabel('標簽3') self.label1.setStyleSheet('background-color: rgb(255, 0, 0)') self.label2.setStyleSheet('background-color: rgb(0, 255, 0)') self.label3.setStyleSheet('background-color: rgb(0, 0, 255)') self.v_layout = QVBoxLayout() #實例化一個垂直布局管理器 self.v_layout.addWidget(self.label1) #將控件添加到垂直布局中,最先添加的出現在最上方 self.v_layout.addWidget(self.label2) self.v_layout.addWidget(self.label3) self.v_layout.setContentsMargins(20,30,40,50) #設置外邊距--到窗口邊框的距離 #參數1 左邊距離 #參數2 上邊距離 #參數3 右邊距離 #參數4 下邊距離 self.v_layout.setSpacing(20) #設置內邊距---各控件之間的距離 self.setLayout(self.v_layout) #將self.v_layout設為整個窗口的最終布局方式 #給self設置布局管理器;給布局管理器設置父對象 if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())

水平布局QHBoxLayout
需要 from PyQt5.QtWidgets import QHBoxLayout
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout
from PyQt5.QtCore import Qt
class Demo(QWidget):
def __init__(self):
super(Demo, self).__init__()
self.label1 = QLabel('標簽1')
self.label2 = QLabel('標簽2')
self.label3 = QLabel('標簽3')
self.label1.setStyleSheet('">self.label2.setStyleSheet('">self.label3.setStyleSheet('">self.v_layout = QHBoxLayout() #實例化一個垂直布局管理器
self.v_layout.addWidget(self.label1) #將控件添加到垂直布局中,最先添加的出現在最上方
self.v_layout.addWidget(self.label2)
self.v_layout.addWidget(self.label3)
self.v_layout.setContentsMargins(20,30,40,50) #設置外邊距--到窗口邊框的距離
#參數1 左邊距離
#參數2 上邊距離
#參數3 右邊距離
#參數4 下邊距離
self.v_layout.setSpacing(20) #設置內邊距---各控件之間的距離
self.setLayout(self.v_layout) #將self.v_layout設為整個窗口的最終布局方式
#給self設置布局管理器;給布局管理器設置父對象
self.setLayoutDirection(Qt.RightToLeft) #設置布局方向
#Qt.RightToLeft 從右到左
#Qt.LeftToRight 從左到右
#Qt.LayoutDirectionAuto 自由布局
if __name__ == '__main__':
app = QApplication(sys.argv)
demo = Demo()
demo.show()
sys.exit(app.exec_())
效果圖:

表單布局QFormLayout
兩列多行 分布的
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit,QFormLayout,QSpinBox,QPushButton,QRadioButton,QHBoxLayout from PyQt5.QtCore import Qt class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,400) label1 = QLabel('姓名:') label2 = QLabel('年齡:') le=QLineEdit() sb=QSpinBox() btn=QPushButton('提交') label2.destroyed.connect(lambda :print('標簽2被銷毀')) sb.destroyed.connect(lambda :print('sb被銷毀')) fl=QFormLayout() #創建表單控件 self.setLayout(fl) fl.addRow(label1,le) #添加行--方式一 #也可以添加布局 fl.addRow(label2,sb) # fl.addRow('姓名(&n):',le) ##添加行--方式二--可以自動綁定小伙伴 # fl.addRow('年齡(&g):',sb) fl.addRow(btn) #只有一個控件時,添加到第1列 rb1 = QRadioButton('男') rb2 = QRadioButton('女') h_layout=QHBoxLayout() h_layout.addWidget(rb1) h_layout.addWidget(rb2) label3 = QLabel('性別:') fl.insertRow(2,label3,h_layout) #插入行 #參數1 位置序號 #如果序號越界就加在最后面 s=fl.rowCount() #返回總行數 s=fl.getWidgetPosition(le) #返回指定控件的位置信息 #(0, 1) 第0行 第1列 s=fl.getLayoutPosition(h_layout) #返回指定布局的位置信息 #(2, 1) s=fl.getWidgetPosition(rb2) #(-1, 1) 第一元素值返回-1 表示控件不在這個布局中 #fl.removeRow(1) #把指定行移出布局(釋放移除的控件) #參數 要移除的行序號 #r=fl.takeRow(1) #把指定行移出布局(不釋放移除的控件) #要把移出的控件隱藏或脫離或添加到其它布局 #label2.hide() #sb.hide() #s=r.labelItem.widget() #返回被移出的0列的控件 #s = r.fieldItem.widget() # 返回被移出的1列的控件 #fl.removeRow(label2) # 把指定行移出布局(釋放移除的控件) #把label2所在行的控件移除 #fl.removeWidget(label2) #移出指定的一個控件(不釋放) le5=QLineEdit() fl.addRow('班級:',le5) s=fl.labelForField(le5) #根據第一列的控件返回第0列控件 s.setText('學校:'*5) fl.setRowWrapPolicy(QFormLayout.WrapLongRows) #設置行策略 #QFormLayout.WrapLongRows 標簽要顯示完整,如果字段列空間不足就移到下一行----沒有效果???? #QFormLayout.WrapAllRows 標簽列和字段列分成兩行顯示 #QFormLayout.DontWrapRows 字段列總是放在標簽列旁邊 s=fl.formAlignment() #返回表單的對齊方式 if s==Qt.AlignLeft | Qt.AlignTop : print('左頂部對齊') fl.setFormAlignment(Qt.AlignLeft | Qt.AlignBottom) #設置表單對齊方式 #對齊看 https://www.cnblogs.com/liming19680104/p/10357263.html fl.setLabelAlignment(Qt.AlignRight) #設置第0列標簽的對齊方式 fl.setVerticalSpacing(20) #設置垂直方向兩行間的間距 fl.setHorizontalSpacing(20) #設置水平方向兩列間的間距 fl.setFieldGrowthPolicy(QFormLayout.ExpandingFieldsGrow) #第1列字段列水平增長策略 #QFormLayout.FieldsStayAtSizeHint=0 保持建議大小,到了建議長度后不在增長 #QFormLayout.ExpandingFieldsGrow=1 只有大小策略設置了Expanding或MinimumExpanding的控件才會被盡可能拉伸占滿布局,否則同FieldsStayAtSizeHint #QFormLayout.AllNonFixedFieldsGrow=2 所有字段欄都可以被拉伸來占滿布局。這是大多數樣式的默認策略 print(s) if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit,QFormLayout,QSpinBox,QPushButton,QRadioButton,QHBoxLayout class Demo(QWidget): def __init__(self): super(Demo, self).__init__() label1 = QLabel('姓名:') label2 = QLabel('年齡:') le=QLineEdit() sb=QSpinBox() btn=QPushButton('提交') fl=QFormLayout() #創建表單控件 self.setLayout(fl) rb1 = QRadioButton('男') rb2 = QRadioButton('女') h_layout=QHBoxLayout() h_layout.addWidget(rb1) h_layout.addWidget(rb2) label3 = QLabel('性別:') fl.setWidget(0,QFormLayout.LabelRole,label1) #設置控件--添加控件 #參數1 行序號 #參數2 控件角色---決定是0列還是1列: #QFormLayout.LabelRole 第0列 #QFormLayout.FieldRole 第1列 #參數3 控件 #注意:如果位置已經存在指令就無效 fl.setWidget(0, QFormLayout.FieldRole, le) fl.setLayout(1, QFormLayout.FieldRole,h_layout) #設置布局--添加布局 if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
網格布局QGridLayout
當使用該布局管理器的時候,你可以把整個窗體想象成帶有格子的,然后只要把各個控件放在相應的格子就好了
需要 from PyQt5.QtWidgets import QGridLayout
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit,QSpinBox,QPushButton,QGridLayout,QVBoxLayout from PyQt5.QtCore import Qt class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,400) label1 = QLabel('標簽1') label11 = QLabel('標簽11') label111 = QLabel('標簽111') label2 = QLabel('標簽2') label3 = QLabel('標簽3') label4 = QLabel('標簽4') label5 = QLabel('標簽5') label1.setStyleSheet('background-color: rgb(255,0,0)') label11.setStyleSheet('background-color: rgb(255,100,0)') label111.setStyleSheet('background-color: rgb(255,0,255)') label2.setStyleSheet('background-color: rgb(0, 251, 0)') label3.setStyleSheet('background-color: rgb(0, 0, 255)') label4.setStyleSheet('background-color: rgb(0, 255, 255)') label5.setStyleSheet('background-color: rgb(100, 0, 255)') le1=QLineEdit() sb2=QSpinBox() btn=QPushButton('提交') gl=QGridLayout() self.setLayout(gl) gl.addWidget(label1,0,0) #添加控件 #參數2 行序號 參數3 列序號 gl.addWidget(label11, 0, 1) gl.addWidget(label111, 0, 2) gl.addWidget(le1,1,0,1,2) #添加控件--帶合並功能 #參數3 占用n行 參數4 占用n列 v=QVBoxLayout() v.addWidget(label3) v.addWidget(label4) v.addWidget(label5) gl.addLayout(v,2,0) #添加布局 s=gl.getItemPosition(3) #返回指定項目的位置信息 #參數 索引序號; #(1, 0, 1, 2) 表示在第一行第0列,占用1行 占用2列 s=gl.itemAtPosition(1,0).widget() #返回指定位置的控件 #gl.setColumnMinimumWidth(0,100) #設置某列最小寬度 #gl.setRowMinimumHeight(0, 50) # 設置某行最小高度 #gl.setColumnStretch(0,1) #設置某列的拉伸系數 #參數1 列序號 參數1 拉伸系數-倍數 gl.setRowStretch(0, 1) # 設置某行的拉伸系數 #參數1 行序號 參數1 拉伸系數-倍數 s=gl.spacing() #返回控件之間的間距 #如果水平間距=垂直間距 就返回間距值 #如果水平間距不等於垂直間距 就返回-1 s=gl.horizontalSpacing() #返回水平間距 s = gl.verticalSpacing() # 返回垂直間距 #gl.setHorizontalSpacing(30) #設置控件之間的水平間距 #gl.setVerticalSpacing(30) #設置控件之間的垂直間距 gl.setSpacing(30) #設置控件之間的垂直間距和水平間距 s=gl.rowCount() #返回總行數 s = gl.columnCount() # 返回總列數 #print(s) if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() gl=demo.layout() #返回布局控件 print(gl) s = gl.cellRect(0, 1) # 返回指定區域的大小 # 參數1 行序號 參數1 列序號--返回0行1列的區域大小 #注意:必須在主窗體顯示之后 #PyQt5.QtCore.QRect(114, 11, 72, 202) print(s) sys.exit(app.exec_())
堆疊布局:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QStackedLayout,QPushButton,QHBoxLayout class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,400) label1 = QLabel('標簽1') label2 = QLabel('標簽2') label3 = QLabel('標簽3') label4 = QLabel('標簽4') label1.setStyleSheet('background-color: rgb(255,0,0)') label2.setStyleSheet('background-color: rgb(0, 251, 0)') label3.setStyleSheet('background-color: rgb(0, 0, 255)') label4.setStyleSheet('background-color: rgb(0, 255, 255)') btn=QPushButton('按鈕') bl=QHBoxLayout() def AA(self): sl.removeWidget(label4) #從布局中移除控件 #不是刪除控件 pass btn.clicked.connect(AA) #********堆疊布局********** sl=QStackedLayout() self.setLayout(bl) bl.addLayout(sl) bl.addWidget(btn) s=sl.addWidget(label1) #添加布局 #返回值 位置索引號 s=sl.addWidget(label2) sl.addWidget(label3) s=sl.currentIndex() #返回當前顯示控件的位置索引號 s=sl.insertWidget(0,label4) #插入控件 #參數1 位置索引號;如果越界,就是現有最大索引號+1 s=sl.widget(0).text() #widget(0) 返回指定索引的控件 sl.setCurrentIndex(2) #顯示指定索引的控件 sl.setCurrentWidget(label3) #顯示指定的控件 s=sl.count() #返回所有控件的總數 sl.setStackingMode(QStackedLayout.StackOne) #設置控件的顯示模式 #QStackedLayout.StackAll 所有控件都可見 #QStackedLayout.StackOne 只有顯示控件可見 其它隱藏-----默認 #信號: sl.currentChanged.connect(self.BB) #顯示控件發生變化時發出信號 #會向槽函數傳遞一個參數---當前顯示控件的序號 sl.widgetRemoved.connect(self.CC) #控件被移除時 # 會向槽函數傳遞一個參數---刪除控件的序號 def BB(self,i): print('顯示控件改變了',i) def CC(self,i): print('控件被移除',i) if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
補充--尺寸策略:
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel,QVBoxLayout,QSizePolicy from PyQt5.QtCore import QSize class Label(QLabel): def minimumSizeHint(self): #最小尺寸函數 return QSize(50,50) def sizeHint(self): #建議尺寸函數 return QSize(200,150) #單位 像素 class Demo(QWidget): def __init__(self): super(Demo, self).__init__() self.resize(300,400) label1 = Label('標簽1') label2 = QLabel('標簽2') label3 = QLabel('標簽3') label4 = QLabel('標簽4') label1.setStyleSheet('background-color: rgb(255,0,0)') label2.setStyleSheet('background-color: rgb(0, 251, 0)') label3.setStyleSheet('background-color: rgb(0, 0, 255)') label4.setStyleSheet('background-color: rgb(0, 255, 255)') bl=QVBoxLayout() #********尺寸策略********** self.setLayout(bl) bl.addWidget(label1) bl.addWidget(label2) bl.addWidget(label3) label1.setMinimumSize(100,100) #設置最小尺寸--修改minimumSizeHint函數值 #label1.setMaximumSize(200,200) #設置最大尺寸 label1.setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred) #設置控件的尺寸策略--方式一 #QSizePolicy.Fixed 固定的---不能改變---尺寸保持sizeHint函數的建議尺寸 #QSizePolicy.Minimum 可以拉伸,但是不能小於sizeHint函數的建議尺寸--sizeHint的尺寸是最小值 #QSizePolicy.Maximum 可以拉伸,但是不能大於sizeHint函數的建議尺寸--sizeHint的尺寸是最大值 #QSizePolicy.Preferred 可以拉伸,但是不能小於minimumSizeHint最小尺寸 #QSizePolicy.Expanding 可以拉伸,拉伸時使本控件盡量占據空間,縮小時不能小於minimumSizeHint最小尺寸 #QSizePolicy.MinimumExpanding 可以拉伸,拉伸時使本控件盡量占據空間,縮小時不能小於sizeHint的尺寸 #QSizePolicy.Ignored 忽略minimumSizeHint尺寸,忽略sizeHint尺寸,縮小時可以為0 #參數1 水平方向的尺寸策略 參數2 垂直方向的尺寸策略 sp=QSizePolicy(QSizePolicy.Preferred,QSizePolicy.Preferred) #創建尺寸策略對象 sp.setRetainSizeWhenHidden(True) # 控件隱藏時是否保留尺寸 #一定要放在setSizePolicy之前 label1.setSizePolicy(sp) #設置控件的尺寸策略--方式二 #label1.hide() if __name__ == '__main__': app = QApplication(sys.argv) demo = Demo() demo.show() sys.exit(app.exec_())
天子驕龍
