代碼:界面與邏輯分離
這是使用Designer
做出的GUI
,然后通過轉換得到的Py
代碼。(界面文件)
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'a.ui'
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(330, 190, 151, 141))
self.label.setText("Hello World")
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
這是手動創建的Py
文件。(邏輯文件)
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow
from firstMainWin import * # 這是你designer轉換后的py文件
class MyMainWindow(QMainWindow,Ui_MainWindow): # 繼承自Ui_MainWindow類(designer轉換后py文件里的類)
def __init__(self, parent=None):
super(MyMainWindow, self).__init__(parent)
self.setupUi(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyMainWindow()
win.show()
sys.exit(app.exec_())
案例:布局管理
提供了4中窗口布局方式,分別是:
Vertical Layout(垂直布局)
:控件默認按照從上到下的順序進行縱向添加Horizontal Layout(水平布局)
:控件默認按照從左到右的順序進行橫向添加Grid Layout(柵格布局)
:將窗口控件放入一個網格之中,並合理規划分成若干行(row)
和列(column)
,並放入合適的單元(cell)
中Form Layout(表單布局)
:控件以兩列的形式布局在表單中,其中左列包含標簽,右列包含輸入控件
一般進行布局有兩種方式:一是通過布局管理器進行布局;二是通過容器控件進行布局
使用布局管理器布局
垂直布局
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
# 創建垂直布局
self.verticalLayout = QVBoxLayout(self)
# 設置控件邊距
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.pushButton = QPushButton(self)
self.pushButton.setText("確認")
self.verticalLayout.addWidget(self.pushButton)
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("取消")
self.verticalLayout.addWidget(self.pushButton1)
self.pushButton2 = QPushButton(self)
self.pushButton2.setText("完成")
self.verticalLayout.addWidget(self.pushButton2)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
水平布局
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
# 創建水平布局
self.verticalLayout = QHBoxLayout(self)
# 設置邊距
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.pushButton = QPushButton(self)
self.pushButton.setText("確認")
self.verticalLayout.addWidget(self.pushButton)
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("取消")
self.verticalLayout.addWidget(self.pushButton1)
self.pushButton2 = QPushButton(self)
self.pushButton2.setText("完成")
self.verticalLayout.addWidget(self.pushButton2)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
柵格布局
計算器模型
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton, QLineEdit
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
# 創建柵格布局
self.gridLayout = QGridLayout(self)
# 設置邊距, 順時針,分別是左,上,右,下。
self.gridLayout.setContentsMargins(5, 5, 5, 5)
# 創建輸入框
self.lineEdit = QLineEdit(self)
# 添加到柵格布局並綁定坐標,x=0, y=0, height=1(高占1格), widgh=4(寬占4格)
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 4)
# 創建按鈕
self.pushButton1 = QPushButton(self)
# 設置按鈕文本
self.pushButton1.setText("1")
self.gridLayout.addWidget(self.pushButton1, 1, 0, 1, 1)
self.pushButton2 = QPushButton(self)
self.pushButton2.setText("2")
self.gridLayout.addWidget(self.pushButton2, 1, 1, 1, 1)
self.pushButton3 = QPushButton(self)
self.pushButton3.setText("3")
self.gridLayout.addWidget(self.pushButton3, 1, 2, 1, 1)
self.pushButton4 = QPushButton(self)
self.pushButton4.setText("4")
self.gridLayout.addWidget(self.pushButton4, 2, 0, 1, 1)
self.pushButton5 = QPushButton(self)
self.pushButton5.setText("5")
self.gridLayout.addWidget(self.pushButton5, 2, 1, 1, 1)
self.pushButton6 = QPushButton(self)
self.pushButton6.setText("6")
self.gridLayout.addWidget(self.pushButton6, 2, 2, 1, 1)
self.pushButton7 = QPushButton(self)
self.pushButton7.setText("7")
self.gridLayout.addWidget(self.pushButton7, 3, 0, 1, 1)
self.pushButton8 = QPushButton(self)
self.pushButton8.setText("8")
self.gridLayout.addWidget(self.pushButton8, 3, 1, 1, 1)
self.pushButton9 = QPushButton(self)
self.pushButton9.setText("9")
self.gridLayout.addWidget(self.pushButton9, 3, 2, 1, 1)
self.pushButton10 = QPushButton(self)
self.pushButton10.setText("+")
self.gridLayout.addWidget(self.pushButton10, 1, 3, 1, 1)
self.pushButton11 = QPushButton(self)
self.pushButton11.setText("-")
self.gridLayout.addWidget(self.pushButton11, 2, 3, 1, 1)
self.pushButton12 = QPushButton(self)
self.pushButton12.setText("*")
self.gridLayout.addWidget(self.pushButton12, 3, 3, 1, 1)
self.pushButton13 = QPushButton(self)
self.pushButton13.setText("/")
self.gridLayout.addWidget(self.pushButton13, 4, 3, 1, 1)
self.pushButton14 = QPushButton(self)
self.pushButton14.setText("計算")
self.gridLayout.addWidget(self.pushButton14, 4, 0, 1, 3)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
表單布局
登錄窗口模型
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFormLayout, QPushButton, QLabel, QLineEdit
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
# 創建表單布局
self.formLayout = QFormLayout(self)
# 設置邊距
self.formLayout.setContentsMargins(0, 0, 0, 0)
self.label = QLabel(self)
self.label.setText("賬號")
self.formLayout.setWidget(0, 0, self.label)
self.lineEdit = QLineEdit(self)
self.formLayout.setWidget(0, 1, self.lineEdit)
self.label1 = QLabel(self)
self.label1.setText("密碼")
self.formLayout.setWidget(1, 0, self.label1)
self.lineEdit1 = QLineEdit(self)
self.formLayout.setWidget(1, 1, self.lineEdit1)
self.pushButton = QPushButton(self)
self.pushButton.setText("確認")
self.formLayout.setWidget(2, 1, self.pushButton)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
使用容器進行布局
所謂容器布局,就是指能夠容納子控件的控件。使用容器控件,目的是將容器控件中的控件歸為一類,以有別於其他控件,當然,容器控件也可以對其子控件進行布局,只不過沒有布局管理其常用。
Frame容器
IP地址檢測模型
盡管是使用了容器布局,但本質上還是使用了布局管理器進行的(通過下面self.verticalLayout.addWidge
代碼可以看出)
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QFrame, QHBoxLayout, QVBoxLayout, QPushButton, QLineEdit, QLabel
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
self.setWindowTitle('IP Check Tools')
self.frame = QFrame(self)
self.frame1 = QFrame(self)
self.verticalLayout = QVBoxLayout(self)
self.horizontalLayout = QHBoxLayout(self.frame)
self.horizontalLayout1 = QHBoxLayout(self.frame1)
self.frames()
self.frames1()
self.verticalLayout.addWidget(self.frame)
self.verticalLayout.addWidget(self.frame1)
"""
首先創建了兩個容器控件frame,和frame1;然后創建frame和frame1各自的水平布局,
frame:
1. 創建好屬於frame的子控件,並添加到屬於frame的水平布局中(self.horizontalLayout)
2. 將frame添加到屬於QWidget的垂直布局中(self.verticalLayout.addWidget(self.frame))
frame1:
1. 創建好屬於frame1的子控件,並添加到屬於frame1的水平布局中(self.horizontalLayout1)
2. 將frame1添加到屬於QWidget的垂直布局中(self.verticalLayout.addWidget(self.frame1))
"""
def frames(self):
self.label = QLabel(self.frame)
self.label.setText("IPv4")
self.horizontalLayout.addWidget(self.label)
self.lineEdit = QLineEdit(self.frame)
self.horizontalLayout.addWidget(self.lineEdit)
self.pushButton= QPushButton(self.frame)
self.pushButton.setText("Check")
self.horizontalLayout.addWidget(self.pushButton)
def frames1(self):
self.label1 = QLabel(self.frame1)
self.label1.setText("IPv6")
self.horizontalLayout1.addWidget(self.label1)
self.lineEdit1 = QLineEdit(self.frame1)
self.horizontalLayout1.addWidget(self.lineEdit1)
self.pushButton1 = QPushButton(self.frame1)
self.pushButton1.setText("Check")
self.horizontalLayout1.addWidget(self.pushButton1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
盡量少用絕對布局
# 參數:控件x坐標,控件y坐標,控件寬度,控件高度
setGeometry(QtCore.QRect(100, 100, 400, 300))
控件間的間隔控件
垂直線
可顯示的布局:
- 水平布局
- 柵格布局(獨占一格)
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QHBoxLayout
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
self.line = QFrame(self)
self.line.setFrameShape(QFrame.VLine) # 設置形狀
self.line.setFrameShadow(QFrame.Sunken) # 設置陰影
self.horizontalLayout = QHBoxLayout(self)
self.pushButton = QPushButton(self)
self.pushButton.setText("Hello")
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("World")
self.horizontalLayout.addWidget(self.pushButton)
self.horizontalLayout.addWidget(self.line)
self.horizontalLayout.addWidget(self.pushButton1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
水平線
可顯示的布局:
- 垂直布局
- 柵格布局(獨占一格)
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QVBoxLayout
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
self.line = QFrame(self)
self.line.setFrameShape(QFrame.HLine)
self.line.setFrameShadow(QFrame.Sunken)
self.verticalLayout = QVBoxLayout(self)
self.pushButton = QPushButton(self)
self.pushButton.setText("Hello")
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("World")
self.verticalLayout.addWidget(self.pushButton)
self.verticalLayout.addWidget(self.line)
self.verticalLayout.addWidget(self.pushButton1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
間隔
注意,需占一格(控件)
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QFrame, QGridLayout, QSpacerItem, QHBoxLayout
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUI()
def setupUI(self):
self.horizontalLayout = QHBoxLayout(self)
self.pushButton = QPushButton(self)
self.pushButton.setText("A for a")
self.horizontalLayout.addWidget(self.pushButton)
# 設置間隔,表示:x=200, y=20,表示:x軸間隔200px, y軸間隔20px
spacerItem = QSpacerItem(200, 20)
self.horizontalLayout.addItem(spacerItem)
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("B for b")
self.horizontalLayout.addWidget(self.pushButton1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())
布局控件尺寸控制
-
minimumSize
:最小尺寸,self.pushButton.setMinimumSize(QtCore.QSize(100, 100))
-
maximumSize
:最大尺寸,self.pushButton.setMaximumSize(QtCore.QSize(300, 300))
-
sizePolicy
:如果窗口控件在布局管理器中的布局不能滿足我們的需求,那么就可以設置該窗口控件的sizePolicy
來實現布局的微調,它也是每個窗口控件所特有的屬性,不同窗口的sizePolicy
可能不同sizeHint
:尺寸提示,窗口控件的期望尺寸minimumSize
:最小尺寸,窗口控件壓縮時所能夠被壓縮到的最小尺寸Horizontal Policy
:水平策略Vertical Policy
:垂直策略
對於策略,相關解釋如下:
-
Fixed
:窗口控件具有其sizeHint
所提示的尺寸且尺寸不會再改變 -
Minimum
:窗口控件的sizeHint
所提示的尺寸就是它的最小尺寸;該控件不能被壓縮得比這個值小,但可以變得更大 -
Maximum
:窗口控件的sizeHint
所提示的尺寸就是它的最大尺寸;該控件不能被壓縮得比這個值大,但它可以被壓縮到minisizeHint
給定的尺寸大小 -
Preferred
:窗口控件的sizeHint
所提示的尺寸就是它的期望尺寸;該窗口控件可以縮小到minisizeHint
所提示的尺寸,也可以變得比sizeHint
所提示的尺寸還要大 -
Expanding
:窗口控件可以縮小到minisizeHint
所提示的尺寸,也可以變得比sizeHint
所提示的尺寸大,但它希望能夠變得更大 -
MinimumExpanding
:窗口控件的sizeHint
所提示的尺寸就是它的最小尺寸,該窗口控件不能被壓縮的比這個值還小,但它希望能夠變得更大 -
Ignored
:無視窗口控件的sizeHint
和minisizeHint
所提示的尺寸,按照默認來設置
語句為:
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton.sizePolicy().hasHeightForWidth())
柵格布局計算器模型
隨着窗口大小而變化
# _*_coding:utf-8 _*_
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QGridLayout, QPushButton, QLineEdit, QSizePolicy
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setMinimumSize(480, 320)
#self.setMaximumSize(1280, 720) # 窗口最大像素
self.btnSizeMin_width = 70
self.btnSizeMin_height = 40
self.btnSizeMax_width = self.btnSizeMin_width * 999
self.btnSizeMax_height = self.btnSizeMin_height * 999
self.setupUI()
def setupUI(self):
self.gridLayout = QGridLayout(self)
self.gridLayout.setContentsMargins(10, 10, 10, 10)
self.lineEdit = QLineEdit(self)
self.lineEdit.setMinimumSize(30, 30) # 最小像素
self.lineEdit.setMaximumSize(999+999, 999) # 最大像素
self.gridLayout.addWidget(self.lineEdit, 0, 0, 1, 4)
self.pushButton1 = QPushButton(self)
self.pushButton1.setText("1")
self.pushButton1.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton1.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton1, 1, 0, 1, 1)
self.pushButton2 = QPushButton(self)
self.pushButton2.setText("2")
self.pushButton2.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton2.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton2, 1, 1, 1, 1)
self.pushButton3 = QPushButton(self)
self.pushButton3.setText("3")
self.pushButton3.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton3.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton3, 1, 2, 1, 1)
self.pushButton4 = QPushButton(self)
self.pushButton4.setText("4")
self.pushButton4.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton4.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton4, 2, 0, 1, 1)
self.pushButton5 = QPushButton(self)
self.pushButton5.setText("5")
self.pushButton5.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton5.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton5, 2, 1, 1, 1)
self.pushButton6 = QPushButton(self)
self.pushButton6.setText("6")
self.pushButton6.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton6.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton6, 2, 2, 1, 1)
self.pushButton7 = QPushButton(self)
self.pushButton7.setText("7")
self.pushButton7.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton7.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton7, 3, 0, 1, 1)
self.pushButton8 = QPushButton(self)
self.pushButton8.setText("8")
self.pushButton8.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton8.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton8, 3, 1, 1, 1)
self.pushButton9 = QPushButton(self)
self.pushButton9.setText("9")
self.pushButton9.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton9.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton9, 3, 2, 1, 1)
self.pushButton10 = QPushButton(self)
self.pushButton10.setText("+")
self.pushButton10.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton10.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton10, 1, 3, 1, 1)
self.pushButton11 = QPushButton(self)
self.pushButton11.setText("-")
self.pushButton11.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton11.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton11, 2, 3, 1, 1)
self.pushButton12 = QPushButton(self)
self.pushButton12.setText("*")
self.pushButton12.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton12.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton12, 3, 3, 1, 1)
self.pushButton13 = QPushButton(self)
self.pushButton13.setText("/")
self.pushButton13.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton13.setMaximumSize(self.btnSizeMax_width, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton13, 4, 3, 1, 1)
self.pushButton14 = QPushButton(self)
self.pushButton14.setText("計算")
self.pushButton14.setMinimumSize(self.btnSizeMin_width, self.btnSizeMin_height)
self.pushButton14.setMaximumSize(self.btnSizeMax_width + 999, self.btnSizeMax_height)
self.gridLayout.addWidget(self.pushButton14, 4, 0, 1, 3)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MainWindow()
win.show()
sys.exit(app.exec_())