Python Pyqt5入门

目录

一、入门——创建简单的界面

二、模块介绍

控件:按钮、文本、输入框(文本框) 

 1、按钮——QPushButton&QRadioButton

2、文本——QLabel

 3、输入框(文本框)——QLineEdit

布局(约束):盒子布局(最常用)、网格布局(九宫格布局)、表单布局、抽屉布局

1、盒子布局——QBoxLayout

2、网格布局(九宫格布局)——QGridLayout

3、表单布局 ——QFormLayout

4、抽屉布局——QStackedLayout

窗口:QWidget、QMainWindow、QDialog

1、QWidget:

2、QMainWindow:

3、QDialog: 

信号与槽:接受信号、自定义信号

1、接受信号

2、自定义信号 

三、ui文件 


一、入门——创建简单的界面

from PyQt5.QtWidgets import QApplication,QWidget

from PyQt5.QtGui import QIcon

import sys

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=QWidget()#创建界面对象

    w.setWindowTitle("第一个标题") #设置窗口标题

    w.resize(300,300)#设置窗口大小

    #w.move(0,0)#设置窗口在屏幕的位置,(0,0)为左上角

    w.setWindowIcon(QIcon("./bg.png"))#设置窗口图标

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果:

二、模块介绍

常用的三个功能模块:

  • QtCore:包含了核心的非GUI的功能。主要和时间、文件与文件夹、各种数据、流、URLs、mime类文件、进程与线程一起使用
  • QtGui:包含了窗口系统、事件处理、2D图像、基本绘画、字体和文字类
  • QtWidgets:包含了一些列创建桌面应用的UI元素

控件:按钮、文本、输入框(文本框) 

 1、按钮——QPushButton&QRadioButton

QPushButton:

from PyQt5.QtWidgets import QApplication,QWidget

import sys

from PyQt5.QtWidgets import QPushButton

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=QWidget()#创建界面对象

    w.setWindowTitle("第一个标题") #设置窗口标题

    #创建按钮

    btn=QPushButton("按钮")

    btn.setParent(w)#设置按钮btn为当前w窗口的,相当于再w窗口中显示这btn按钮

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果: 

按钮

 QRadioButton:

from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication,QWidget

from PyQt5.QtGui import QIcon

import sys

from PyQt5.QtWidgets import QRadioButton

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=QWidget()

    w.resize(300,300)

    btn1=QRadioButton("男",w)

    btn1.setGeometry(10,0,30,30)#按钮存放的位置,在(20,20)位置,宽高为(300,30)

    btn2=QRadioButton("女",w)

    btn2.setGeometry(40,0,30,30)

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果: 

2、文本——QLabel

from PyQt5.QtWidgets import QApplication,QWidget

from PyQt5.QtWidgets import QLabel

import sys

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=QWidget()#创建界面对象

    w.setWindowTitle("第一个标题") #设置窗口标题

    #创建文本

    #方法一(同上,使用调用方法来指定父类)

    label=QLabel("账号:")

    label.setParent(w)

    #方法二(创建时就指定父类)

    label=QLabel("账户:",w)

   

    #设置文本位置与大小

    label.setGeometry(20,20,300,30)#在(20,20)位置,宽高为(300,30)

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果: 

 

注意:

文本位置:是以红色点为原点

 3、输入框(文本框)——QLineEdit

from PyQt5.QtWidgets import QApplication,QWidget

from PyQt5.QtWidgets import QLabel

from PyQt5.QtWidgets import QLineEdit

import sys

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=QWidget()#创建界面对象

    w.setWindowTitle("第一个标题") #设置窗口标题

    #创建文本

    label=QLabel("账户:",w)

    #设置文本位置与大小

    label.setGeometry(20,20,300,30)#在(20,20)位置,宽高为(300,30)

    #创建文本框(输入框)

    edit=QLineEdit(w)

    edit.setPlaceholderText("请输入账号")

    edit.setGeometry(55,20,200,20)

    

    #创建按钮

    btn=QPushButton("按钮",w)

    btn.setGeometry(50,80,70,30)

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果:

总结&补充:

①设置位置大小:xx.setGeometry(x,y,w,h) #xx为控件对象,(x,y),宽w,高h

②返回位置大小:xx.frameGeometry().getRect()   #元组

③去掉标题栏(即窗口标题与图标不显示):from PyQt5 import Qt      w.setWindowFlags(Qt.Qt.CustomizeWindowHint)

布局(约束):盒子布局(最常用)、网格布局(九宫格布局)、表单布局、抽屉布局

使用布局器时,控件可以不指定父对象,直接加入到布局器即可。

(即在最后时,让当前窗口的布局器使用这个布局器:self.setLayout(layout) )

1、盒子布局——QBoxLayout

一般使用它的两个子类QHBoxLayout(水平)和QVBoxLayout(垂直)

from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication,QWidget,QPushButton

from PyQt5.QtGui import QIcon

import sys

from PyQt5.QtWidgets import QVBoxLayout

class MyWindow(QWidget):

    def __init__(self) :

        super(QWidget,self).__init__()

        self.setWindowTitle("第一个标题")

        self.resize(300,300)

        #垂直布局

        layout=QVBoxLayout()

        btn1=QPushButton("按钮1")

        layout.addWidget(btn1)#添加到布局器

        btn2=QPushButton("按钮2")

        layout.addWidget(btn2)

        btn3=QPushButton("按钮3")

        layout.addWidget(btn3)

        #layout.addStretch(2)#添加一个伸缩器(用于分配布局器在页面的布局)

        self.setLayout(layout)#让当前窗口的布局器使用这个布局器

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=MyWindow()

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

效果:

综合应用:

 from PyQt5 import QtCore

from PyQt5.QtWidgets import QApplication,QWidget,QPushButton

from PyQt5.QtGui import QIcon

import sys

from PyQt5.QtWidgets import QVBoxLayout

from PyQt5.QtWidgets import QHBoxLayout

from PyQt5.QtWidgets import QGroupBox

from PyQt5.QtWidgets import QRadioButton

class MyWindow(QWidget):

    def __init__(self) :

        super(QWidget,self).__init__()

        self.init_ui()

    def init_ui(self):

        self.setWindowTitle("第一个标题")

        self.resize(300,300)

       

        #“爱好”

        hobby_group=QGroupBox("爱好")#创建一个“爱好组”(相当于将“爱好”设置一个组,可以作为垂直布局的一个标题)

        h_layout=QVBoxLayout()#创建“爱好”的垂直布局

        btn1=QRadioButton("抽烟")

        btn2=QRadioButton("喝酒")

        btn3=QRadioButton("唱歌")

        h_layout.addWidget(btn1)

        h_layout.addWidget(btn2)

        h_layout.addWidget(btn3)

        hobby_group.setLayout(h_layout)

       

        #“性别”

        gender_group=QGroupBox("性别")#创建一个“性别组”(相当于将“性别”设置一个组,可以作为水平布局的一个标题)

        g_layout=QHBoxLayout()#创建“性别”的水平布局

        btn4=QRadioButton("男")

        btn5=QRadioButton("女")

        g_layout.addWidget(btn4)

        g_layout.addWidget(btn5)

        gender_group.setLayout(g_layout)

       

        #外层上下布局:将“爱好”与“性别”同时放入一个垂直布局里,最后让当前窗口的布局器使用这个布局器

        container=QVBoxLayout()

        container.addWidget(hobby_group)

        container.addWidget(gender_group)

        self.setLayout(container)#让当前窗口的布局器使用这个布局器

if __name__=="__main__":

    app=QApplication(sys.argv)#相当于打开界面(①不能少)

    w=MyWindow()

    w.show()#展示窗口

    app.exec_()#程序进行循环等待状态 相当于检测界面(②不能少)

总结:1、布局中嵌套控件、组(都用:布局.addWidget(控件/组))

2、组嵌套布局(都用:组.setLayout(布局) )

3、当前窗口使用这个布局(self.setLayout(布局))

2、网格布局(九宫格布局)——QGridLayout

import sys

from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QLineEdit

from PyQt5.QtWidgets import QGridLayout

class MyWindow(QWidget):

    def __init__(self):

        super().__init__()

        self.init_ui()

    def init_ui(self):

        self.setWindowTitle("计算器")

        ## 输入框

        edit = QLineEdit()

        edit.setPlaceholderText("请输入内容")

        ## 网格布局

        grid = QGridLayout()

        #方法一:

        # 准备数据

        data = {

            0: ["7", "8", "9", "+", "("],

            1: ["4", "5", "6", "-", ")"],

            2: ["1", "2", "3", "*", "<-"],

            3: ["0", ".", "=", "/", "C"]

        }

        #循环创建追加进去

        for line_number, line_data in data.items():

            # 此时line_number是第几行,line_data是当前行的数据

            for col_number, number in enumerate(line_data):

                # 此时col_number是第几列,number是要显示的符号

                btn = QPushButton(number)

                # grid.addWidget(btn)

                grid.addWidget(btn, line_number, col_number)

        #方法二:

        data=[["7", "8", "9", "+", "("],

             ["4", "5", "6", "-", ")"],

           ["1", "2", "3", "*", "<-"],

             ["0", ".", "=", "/", "C"]]

        for i in range(4):

            for j in range(5):

                btn=QPushButton(data[i][j])

                grid.addWidget(btn,i,j) #网格的行i,列j

       

        ##整体垂直布局

        layout = QVBoxLayout()

        layout.addWidget(edit)# 把输入框添加到整体垂直布局中

        layout.addLayout(grid)# 把网格布局追加到整体垂直布局中

        self.setLayout(layout)

if __name__ == '__main__':

    app = QApplication(sys.argv)

    w = MyWindow()

    w.show()

    app.exec()

效果:

总结:1、布局嵌套控件:布局.addWidget(控件)

2、布局嵌套布局:嵌套.addLayout(被嵌套)

3、表单布局 ——QFormLayout

用于页面注册页面登录

import sys

from PyQt5.QtCore import Qt

from PyQt5.QtWidgets import QVBoxLayout, QLineEdit, QPushButton, QApplication, QWidget

from PyQt5.QtWidgets import QFormLayout

class MyWindow(QWidget):

    def __init__(self):

        super().__init__()

        self.init_ui()

    def init_ui(self):

        # 设定当前Widget的宽高(可以拉伸大小)

        # self.resize(300, 200)

        # 禁止改变宽高(不可以拉伸)

        self.setFixedSize(300, 150)

        # 表单容器

        form_layout = QFormLayout()

        # 创建1个输入框

        edit = QLineEdit()

        edit.setPlaceholderText("请输入账号")

        form_layout.addRow("账号:", edit)

        # 创建另外1个输入框

        edit2 = QLineEdit()

        edit2.setPlaceholderText("请输入密码")

        form_layout.addRow("密码:", edit2)

        # 外层容器

        container = QVBoxLayout()

        # 将from_layout添加到垂直布局器中

        container.addLayout(form_layout)

        # 按钮

        login_btn = QPushButton("登录")

        login_btn.setFixedSize(100, 30)

        # 把按钮添加到容器中,并且指定它的对齐方式

        container.addWidget(login_btn, alignment=Qt.AlignRight)

       

        # 设置当前Widget的布局器,从而显示这个布局器中的子控件

        self.setLayout(container)


 

if __name__ == '__main__':

    app = QApplication(sys.argv)

    w = MyWindow()

    w.show()

    app.exec()

效果:

总结:

表单(布局)嵌套控件:表单.addRow('名称:',控件)

【这里也可以用表单(布局).addWidget(控件),但是就失去了表单存在的意义】

4、抽屉布局——QStackedLayout

用于多页面切换的布局,一次只能看到一个界面。(类似于电脑端微信聊天页面)

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton, QStackedLayout, QLabel

class Window1(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("我是抽屉1要显示的内容", self)
        self.setStyleSheet("background-color:green;")

class Window2(QWidget):
    def __init__(self):
        super().__init__()
        QLabel("我是抽屉2要显示的内容", self)
        self.setStyleSheet("background-color:red;")

class MyWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.resize(300,300)
        self.create_stacked_layout()
        self.init_ui()
    def create_stacked_layout(self):#创建抽屉布局,用于界面显示变换的内容
        self.stacked_layout=QStackedLayout()
        win1=Window1()
        win2=Window2()
        self.stacked_layout.addWidget(win1)
        self.stacked_layout.addWidget(win2)
    def init_ui(self):
        container=QVBoxLayout()#整体
        #创建一个widget,嵌入stacked_layout(使其成为一个类似对话框的界面)。注:布局嵌套widget用addWidget
        #这里仅是为了使界面呈现出一个对话框的效果(即为“抽屉布局”界面设置背景颜色),也可以不引入一个widget
        #不加则把从这里开始的后四行注释,后面container.addLayout(self.stacked_layout)取消注释
        w=QWidget()
        w.setLayout(self.stacked_layout)
        w.setStyleSheet("background-color:grey;")
        container.addWidget(w)
        
        btn1=QPushButton("按钮1")
        btn2=QPushButton("按钮2")
        btn1.clicked.connect(self.btn1_pressed)#点击关联事件
        btn2.clicked.connect(self.btn2_pressed)    
        #container.addLayout(self.stacked_layout)
        container.addWidget(btn1)
        container.addWidget(btn2)
        
        self.setLayout(container)
    def btn1_pressed(self):
        self.stacked_layout.setCurrentIndex(0)#注只有抽屉布局才能用setCurrentIndex来切换当前内容
    def btn2_pressed(self):
        self.stacked_layout.setCurrentIndex(1)

效果:

 

窗口:QWidget、QMainWindow、QDialog

1、QWidget:

控件和窗口的父类 ,自由度高(什么都东西都没有),没有划分菜单、工具栏、状态栏、主窗口 等区域

2、QMainWindow:

QWidget的子类,包含菜单栏,工具栏,状态栏,标题栏等,中间部分则为主窗口区域

3、QDialog: 

 对话框窗口的基类

总结:登录窗口可用:QDialog、 自己设计建议用:QWidget、QMainWindow有菜单栏(根据实际情况选择)

信号与槽:接受信号、自定义信号

1、接受信号

例如:按钮点击

import sys

from PyQt5.QtWidgets import QApplication,QWidget,QPushButton

class MyWindow(QWidget):

    def __init__(self):

        super().__init__()

        self.init_ui()

    def init_ui(self):

        self.resize(300,300)

        btn=QPushButton("按钮",self)

        btn.clicked.connect(self.moment)

    def moment(self):

        print("已被点击。")

if __name__ == "__main__":

    app = QApplication(sys.argv)

    win = MyWindow()

    win.show()

    app.exec()

效果: 

2、自定义信号 

 import sys

from PyQt5.QtWidgets import QApplication,QWidget,QPushButton

from PyQt5.QtCore import pyqtSignal

class MyWindow(QWidget):

    my_signal=pyqtSignal(str)#声明一个信号 只能放在函数的外面(str说明只接受字符串

    def __init__(self):

        super().__init__()

        self.init_ui()

    def init_ui(self):

        self.resize(300,300)

        btn=QPushButton("开始检测",self)

        btn.setGeometry(20,20,100,50)

        btn.clicked.connect(self.detection)

        self.my_signal.connect(self.my_slot)#绑定信号与槽

    def my_slot(self,msg):#这里emit()一定要传一个字符串参数

        print(">>>>",end='')

    def detection(self):

        print("开始检测:")

        msg="发现bug"

        for i in range(1,101):

            if i%5==0:

                self.my_signal.emit(msg)#发射信号(触发执行my_signal绑定的槽函数my_slot())。这里emit()一定要传一个字符串参数

            print("192.169.1.{}".format(i))

if __name__ == "__main__":

    app = QApplication(sys.argv)

    win = MyWindow()

    win.show()

    app.exec()        

效果:

综合应用:

将输出在终端的结果在窗口上显示

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QVBoxLayout,QLabel,QHBoxLayout,QScrollArea
from PyQt5.QtCore import pyqtSignal,Qt
class MyWindow(QWidget):
    my_signal=pyqtSignal(str)#声明一个信号 只能放在函数的外面
    def __init__(self):
        super().__init__()
        self.msg_lst=[]#记录msg内容
        self.init_ui()
    def init_ui(self):
        self.resize(500,200)
        self.container=QVBoxLayout()#整体
        self.content_layout=QVBoxLayout()
        self.button_layout=QHBoxLayout()
        
        self.msg=QLabel("111")#QLabel可以放入图片或文字
        self.msg.resize(440,15)
        self.msg.setWordWrap(True)#自动换行
        self.msg.setAlignment(Qt.AlignTop)#靠上
        self.msg.setStyleSheet("background-color:yellow;color:grey")
        #创建一个滚动对象
        scroll=QScrollArea()
        scroll.setWidget(self.msg)#设置对msg进行滚动,因为原先msg(QLabel)大小只有(440,15)
        self.content_layout.addWidget(scroll)#垂直布局器添加自动滚动条(注:有滚动要配合布局器使用)
        
        btn=QPushButton("开始检测")
        btn.setGeometry(20,20,100,50)
        self.button_layout.addStretch()
        self.button_layout.addWidget(btn)
        self.button_layout.addStretch()
        btn.clicked.connect(self.detection)
        
        self.my_signal.connect(self.my_slot)#绑定信号与槽
        
        self.container.addLayout(self.content_layout)
        self.container.addLayout(self.button_layout)
        self.setLayout(self.container)
        
    def my_slot(self,msg):#函数作用:将结果展示在屏幕上 #这里emit()一定要传一个参数
        self.msg_lst.append(msg)#接受一个msg后保存结果(即将所有得到的msg存起来,便于后续展示)
        self.msg.setText("<br>".join(self.msg_lst))#设置msg(QLabel)内容
        self.msg.resize(400,len(self.msg_lst)*15)#手动扩大:扩大msg(QLabel)大小,展示msg内容
        self.msg.repaint()#更新内容,如果不更新可能没有显示新内容
        
    def detection(self):
        print("开始检测:")
        for i in range(1,101):
            msg="192.168.0."+str(i)
            if i%5==0:
                msg=">>>" +msg   
            self.my_signal.emit(msg)#发射信号(触发执行my_signal绑定的槽函数my_slot)。这里emit()一定要传一个参数
            print("{}".format(msg))
    
if __name__ == "__main__":
    app = QApplication(sys.argv)

    win = MyWindow()
    win.show()

    app.exec()      

效果:

总结注意点:

展示文字QLabel() ——>要在屏幕上展示,布局大小不够时——>添加滚动对象QScrollArea()——>因滚动对象要配合布局器使用——>垂直布局器QVBoxLayout()

因此:布局器QVBoxLayout() 嵌套 滚动对象QScrollArea() 再嵌套 QLabel()

三、ui文件 

纯代码编写界面效率低,可以用Qt Designer来辅助设计图形化界面

1、在Python中加载ui文件:

import sys

from PyQt5.QtWidgets import QApplication

from PyQt5 import uic

if __name__=='__main__':

    app=QApplication(sys.argv)

    ui=uic.loadUi('./MainWindow.ui')

    ui.show()

    app.exec_()

 2、ui文件转py文件:

 终端在demo.ui目录下使用命令行:python -m PyQt5.uic.pyuic demo.ui -o demo.py

本篇为以下课程的学习笔记,仅做学习记录:

【PyQt5 快速入门】 https://www.bilibili.com/video/BV1LT4y1e72X/?p=33&share_source=copy_web&vd_source=4c701974d440a1de8021c328bad2ef26

  • 22
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值