栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

学习PyQt5之路

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

学习PyQt5之路

目录
  • 1 晚上一个小项目
  • 2 刘金玉编程学习过程
    • 2.1 补充pyuic命令解析
    • 2.2 PyQt5与Qtdesigner的一些对照分析
    • 2.3 PyQt5设置窗体图标
    • 2.4 PyQt5显示提示框
    • 2.5 PyQt5类封装
    • 2.6 PyQt5消息盒子QMesageBox
    • 2.7 PyQt5窗体居中和布局
    • 2.8 PyQt5窗体的绝对布局和相对布局
    • 2.9 PyQt5按钮控件QPushButton应用案例,程序三原色
    • 2.10 PyQt5单行文本框QLineEdit文本改变事件
    • 2.11 PyQt5复选框QCheckBox控件状态事件应用
    • 2.12 PyQt5滑块控件QSlider应用

1 晚上一个小项目

今晚上跑了一个Pycharm上的Qt-5的翻译代码,记录如下
test.py由designer生成自己再改动一下

from PyQt5 import QtCore, QtGui, QtWidgets
from fanyi import Fanyi

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1027, 816)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget)
        self.textBrowser.setGeometry(QtCore.QRect(350, 120, 171, 71))
        self.textBrowser.setStyleSheet("background-color: rgb(107, 255, 193);")
        self.textBrowser.setObjectName("textBrowser")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(340, 550, 331, 31))
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout_4 = QtWidgets.QGridLayout(self.layoutWidget)
        self.gridLayout_4.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.pushButton_3 = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.gridLayout_4.addWidget(self.pushButton_3, 0, 0, 1, 1)
        self.pushButton_2 = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout_4.addWidget(self.pushButton_2, 0, 1, 1, 1)
        self.layoutWidget1 = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget1.setGeometry(QtCore.QRect(180, 270, 625, 233))
        self.layoutWidget1.setObjectName("layoutWidget1")
        self.gridLayout_3 = QtWidgets.QGridLayout(self.layoutWidget1)
        self.gridLayout_3.setContentsMargins(0, 0, 0, 0)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setObjectName("gridLayout")
        self.textEdit = QtWidgets.QTextEdit(self.layoutWidget1)
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 1, 0, 1, 1)
        self.label = QtWidgets.QLabel(self.layoutWidget1)
        self.label.setStyleSheet("background-color: rgb(255, 216, 119);n"
"font: 18pt "楷体";")
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
        self.gridLayout_3.addLayout(self.gridLayout, 0, 0, 1, 1)
        self.pushButton = QtWidgets.QPushButton(self.layoutWidget1)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout_3.addWidget(self.pushButton, 0, 1, 1, 1)
        self.gridLayout_2 = QtWidgets.QGridLayout()
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.textEdit_2 = QtWidgets.QTextEdit(self.layoutWidget1)
        self.textEdit_2.setObjectName("textEdit_2")
        self.gridLayout_2.addWidget(self.textEdit_2, 1, 0, 1, 1)
        self.label_2 = QtWidgets.QLabel(self.layoutWidget1)
        self.label_2.setStyleSheet("background-color: rgb(152, 176, 255);n"
"font: 18pt "隶书";n"
"background-color: rgb(255, 225, 107);")
        self.label_2.setObjectName("label_2")
        self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1)
        self.gridLayout_3.addLayout(self.gridLayout_2, 0, 2, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1027, 26))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.pushButton_2.clicked.connect(self.textEdit_2.close)
        self.pushButton_3.clicked.connect(self.textEdit.clear)
        self.pushButton_3.clicked.connect(self.textEdit_2.clear)
        self.pushButton.clicked.connect(self.translation)

        QtCore.QmetaObject.connectSlotsByName(MainWindow)
    def translation(self):
        if self.textEdit.toPlainText()=='':
            context='None'
        else:
            context= self.textEdit.toPlainText()
        st=Fanyi(context)
        self.textEdit_2.setText(st)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.textBrowser.setHtml(_translate("MainWindow", "n"
"n"
"p, li { white-space: pre-wrap; }n"
"n"
"

爬虫翻译

")) self.pushButton_3.setText(_translate("MainWindow", "清除所有文本")) self.pushButton_2.setText(_translate("MainWindow", "关闭窗口")) self.label.setText(_translate("MainWindow", "请输入翻译内容")) self.pushButton.setText(_translate("MainWindow", "翻译")) self.label_2.setText(_translate("MainWindow", "翻译结果"))

fanyi.py 有道翻译代码块,只能翻译一句话

# -*- coding:utf-8 -*-
import requests

# 把代码封装成函数更python
def Fanyi(word):
    url = 'http://fanyi.youdao.com/translate?smartresult=dict&smartresult=rule'
    data = {'i': word,
            'from': 'AUTO',
            'to': 'AUTO',
            'smartresult': 'dict',
            'client': 'fanyideskweb',
            'doctype': 'json',
            'version': '2.1',
            'keyfrom': 'fanyi.web',
            'action': 'FY_BY_REALTIME',
            'typoResult': 'false'}
    # 将需要post的内容,以字典的形式记录在data内。
    r = requests.post(url, data=data)
    # post需要输入两个参数,一个url,一个是data,返回的是一个Response对象
    answer = r.json()
    result = answer['translateResult'][0][0]['tgt']
    # print('"'+ word + '"的翻译结果:' + result + 'n')
    return result

# if __name__=="__main__":  #自己设计输入结束的条件,原谅我懒弄了个死循环
#     Fanyi(input('请输入:'))

run_test.py 主程序代码块。

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow
import test

if __name__=='__main__':
    app=QApplication(sys.argv)

    mainW=QMainWindow()
    ui=test.Ui_MainWindow()
    ui.setupUi(mainW)

    mainW.show()
    sys.exit(app.exec_())

最后界面

2 刘金玉编程学习过程 2.1 补充pyuic命令解析


2.2 PyQt5与Qtdesigner的一些对照分析
函数或语句功能
move(x,y)移动窗体
resize(w,h)调整窗体大小
exec_()表示程序界面监听事件的开始,是一个死循环
类库或类包功能
QtWidgets管理各控件的一个基类
QApplication应用程序类
QtGui设置图标、字体等的类包
sysPython系统类库
2.3 PyQt5设置窗体图标

设置窗体标题

  def retranslateUi(self, Form):
      _translate = QtCore.QCoreApplication.translate
      Form.setWindowTitle(_translate("Form", "佳明"))

或者在前面

Form.setWindowTitle("世界")

设置图标

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QIcon  # 注意此处继续导入类库

Form.setWindowIcon(QIcon("img\fig1.png"))  # 自己选择放置位置

图标较好的下载位置:iconfont,下载尽量使用png或者gif,可使得图片背景透明.
在项目中,我们往往将所有图标放到同一个文件夹中,然后通过同一个相对路径进行调用.
设置两个窗口不同图标所有代码

#  new1.py
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QIcon

class Ui_Form(object):
  def setupUi(self, Form):
      Form.setObjectName("Form")
      Form.resize(622, 511)
      Form.setWindowTitle("世界")
      self.retranslateUi(Form)

      QtCore.QmetaObject.connectSlotsByName(Form)

  def retranslateUi(self, Form):
      _translate = QtCore.QCoreApplication.translate
#  run_new1.py
import sys
from PyQt5.QtWidgets import QApplication,QWidget
import new1
from PyQt5.QtGui import QIcon

if __name__=='__main__':
  app=QApplication(sys.argv)

  mainW=QWidget()
  ui=new1.Ui_Form()
  ui.setupUi(mainW)
  mainW.setWindowIcon(QIcon("img\fig1.png"))
  mainW2=QWidget()
  ui2=new1.Ui_Form()
  ui2.setupUi(mainW2)
  mainW2.setWindowIcon(QIcon("img\fig2.png"))

  mainW.show()
  mainW2.show()
  sys.exit(app.exec_())


通过QWidget的setWindowlcon设置出来的窗体的图标,可以是每个窗体一个图标.
通过Qapplication的setWindowlcon设置出来的窗体的图标,可以是每个窗体用一样的图标
如果把框体没有单独设置窗体图标,那么使用Qapplication的setWindowlcon会统一设置

# mainW2.setWindowIcon(QIcon("img\fig2.png"))
app.setWindowIcon(QIcon("img\fig1.png"))

2.4 PyQt5显示提示框

使用函数setToolTip,基本上所有的控件和窗体都有这个函数.
使用格式: 控件对象.setToolTip(“需要提示的字符串”)
按钮和控件都是作为类的存在
小技巧:系统中文件查找加可以搜索所有包含这个关键词的所有文件*

如何查找所需要的类?
我们可以在Pycharm上,通过Ctrl+PyQt5到其代码,再右键__init__.py,open in File Path找到PyQt5文件安装所在位置.
然后利用模糊查找找到我们所需要的类的位置.
后到程序中去找到对应类.

下面为 显示提示框代码 run_new1.py。

# 需要导入QToolTip类库,通过QToolTip的setFont方法设置文字样式
# 需要导入Qfont类库,实例化Qfont类进行文字样式设置,这个显示样式的设置是在全局样式中呈现效果的

import sys, new1
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,QToolTip
from PyQt5.QtGui import QIcon, QFont

if __name__=='__main__':
    app=QApplication(sys.argv)
    QToolTip.setFont(QFont('隶书',40))

    W=QWidget()
    ui=new1.Ui_Form()
    ui.setupUi(W)

    W.setWindowIcon(QIcon("img\fig1.png"))
    W.setToolTip("你忘记吃饭了")
    # 实例化一个按钮(按钮文字,父容器)
    btn=QPushButton("老师",W)   # 此按钮类最终是继承了QWidget这个类型
    btn.move(250,250)  # 对按钮在父容器中的位置进行控制
    btn.setToolTip("我知道你吃了饭")
    btn.setFont(QFont('隶书',33))

    W.show()
    sys.exit(app.exec_())

2.5 PyQt5类封装

作为优秀的程序员应当擅于类封装.
同时我们要会用纯代码来写PyQt5程序.

一个很粗略的自定义类

class Myclass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()
    def initUI(self):
        # self.move(20,20)
        # self.resize(300,300)
        self.setGeometry(20,20,300,300)
        btn=QPushButton("老师",self)
        btn.move(50,50)
        btn.clicked.connect(self.close)
        self.show()

if __name__ == "__main__" :
    app=QApplication(sys.argv)
    mc=Myclass()
    app.exec_()  # 死循环监听窗体上所有信号

窗体上对GUI的行为都是对某个事件的行为,GUI被事件驱动.
其它方式编程做相应改写即可.

信号槽的简单使用:
格式:信号源.信号.connect(槽)
格式解释:信号源(按钮)信号(clicked)connect(某个事件方法)
注意在绑定信号槽的过程中,我们的槽方法不能加括号.

2.6 PyQt5消息盒子QMesageBox

目标效果:点击按钮出现消息选择框,再选择下一个按钮.
不同图标的消息类别:带有图标的消息盒子,图标可以是问号question,信息information,警告warning,当然也可以自定义其它
思路:
前面程序当点击关闭按钮的时候,执行的是窗体的关闭,而窗体的关闭等同于点击窗体右上角的关闭X的自带按钮的效果,这个效果是QWidget基类所实现的.
那么我们可以重写父类的关闭实现方法来实现其它关闭效果.
下面进入到QWidget里面查找close方法并做相应复制后改写.

如何阻止事件关闭.
event.accept() 同意操作
event.ignore() 忽略操作
主要代码

import sys
from PyQt5.QtWidgets import QApplication, QMessageBox,QWidget,QPushButton,QToolTip
from PyQt5.QtGui import QIcon, QFont

class Myclass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        QToolTip.setFont(QFont('隶书', 40))
        self.setGeometry(500,250,622, 511)
        self.setWindowTitle("世界")
        self.setWindowIcon(QIcon("img\fig1.png"))
        self.setToolTip("你忘记吃饭了")
        btn = QPushButton("老师", self)  # 此按钮类最终是继承了QWidget这个类型
        btn.move(300,300)
        btn.setToolTip("我知道你吃了饭")
        btn.setFont(QFont('隶书', 33))
        btn.clicked.connect(self.close)
        self.show()

    def closeEvent(self, event):  # 重写后名称可自己定义,这里为event
        print("你的名字:")
        # 重写关闭事件,最后一个为默认,格式:(self,消息标题,消息内容,默认按钮),最后返回一个选中结果
        result=QMessageBox.question(self,"温馨提示您:","您真的要关闭窗体吗?",QMessageBox.Yes|QMessageBox.No,QMessageBox.Yes)
        if result==QMessageBox.Yes:
            event.accept()
        else:
            event.ignore()
            QMessageBox.information(self,"消息","谢谢!")

if __name__=="__main__":
    app=QApplication(sys.argv)
    ui=Myclass()
    app.exec_()

2.7 PyQt5窗体居中和布局

默认情况下,窗体位置居中.
标签文本控件 导入类库QLabel

lbl=QLabel("你快乐吗?",self)

利用width手动设计居中效果

if __name__=="__main__":
    app=QApplication(sys.argv)
    dk=app.desktop()
    ui=Myclass()
    ui.move(dk.width()/3,50) # 桌面居中
    ui.move(dk.width()/2-ui.width()/2,50)  # 水平居中
    # 同样使用.height()算高度
    app.exec_()

绝对布局:直接通过move到某个像素点的位置,好处是非常灵活.

2.8 PyQt5窗体的绝对布局和相对布局

相对布局是指布局中的控件可以随着窗体的变化而变化,布局中控件之间的距离可以按照比例来调节.
导入类QVBoxLayout,QHBoxLayout,QGridLayout来进行垂直布局、水平布局、网格布局
这里面我们使用了QLineEdit 单行输入文本框
水平布局,后面几种均为相对布局.

 self.setGeometry(app.desktop().width()/2-self.width()/2,50,400,300)
 
 lelcode=QLabel("验证码",self)
 lecode=QLineEdit(self)
 btncode=QPushButton("验证",self)

 hlayout=QHBoxLayout(self)  # 所有控件只能在水平方向排列
 hlayout.addWidget(lelcode)
 hlayout.addWidget(lecode)
 hlayout.addWidget(btncode)


垂直布局

lelcode=QLabel("验证码",self)
lecode=QLineEdit(self)
btncode=QPushButton("验证",self)

vlayout=QVBoxLayout(self)
vlayout.addWidget(lelcode)
vlayout.addWidget(lecode)
vlayout.addWidget(btncode)
vlayout.addStretch()  # 弹簧,比例为空白部分


网格布局

lbltitle=QLabel("标题")
blauthor=QLabel("作者")
lblcontent=QLabel("内容")

letitle=QLineEdit()
leauthor=QLineEdit()
lecontent=QTextEdit()

grid=QGridLayout(self)
# grid.setSpacing(20)   # 设置空格,此外还有很多额外设置
grid.addWidget(lbltitle,0,0)
grid.addWidget(letitle,0,1)
grid.addWidget(lblauthor,1,0)
grid.addWidget(leauthor,1,1)
grid.addWidget(lblcontent,2,0)
grid.addWidget(lecontent,2,1)


多行文本框有很多基本的功能.

2.9 PyQt5按钮控件QPushButton应用案例,程序三原色

制作三原色可调换界面.
思路:
(一)制作界面采用PyQt5进行布局
(二)采用盒子布局的方法进行界面布局
(三)按钮的状态功能加入
(四)设置Qframe的背景颜色
(五)设置按钮的点击事件
(六)设置三原色的情况,最终还是要通过改变Qframe的样式来实现颜色变化
完整代码如下,背景颜色可随着按钮点击不同而变化。

import sys
from PyQt5.QtWidgets import QApplication,QWidget,QPushButton,Qframe,QVBoxLayout,QHBoxLayout
from PyQt5.QtGui import QColor

class Myclass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("我的三原色")
        # 下面设置类中全局变量,此中红、绿、蓝取值范围为0-255
        self.color=QColor(0,0,0)
        dk=app.desktop()
        self.setGeometry(dk.width()/4-self.width()/4,200,400,300)

        btnRed=QPushButton("红")
        # 使用 setCheckable方法可以设置按钮是否可以选中与不选中的状态切换,默认情况下此方法设置的值为False
        btnRed.setCheckable(True)
        # 槽函数的定义要看我们的信号源是否有参数,信号源中有参数的部分的信号参数需要使用中括号
        btnRed.clicked[bool].connect(self.setColor)
        btnGreen = QPushButton("绿")
        btnGreen.setCheckable(True)
        btnGreen.clicked[bool].connect(self.setColor)
        btnBlue = QPushButton("蓝")
        btnBlue.setCheckable(True)
        btnBlue.clicked[bool].connect(self.setColor)

        vlo=QVBoxLayout() # 垂直方向
        vlo.addWidget(btnRed)
        vlo.addWidget(btnGreen)
        vlo.addWidget(btnBlue)

        # 框架容器 Qframe,必须使用类库 Qframe,这里面水平右侧隔开一段空白
        # 初始化为上面语句,父容器可以采用后期添加到盒式布局的方式进行设置,也可以在初始化时设置
        # 父容器的设置会影响子容器的生命周期
        self.myframe=Qframe()

        # 控件设置CSS风格,可以通过setStylesheet方法来设置,此法几乎在所有QWidget的控件上都能实现
        # 设置默认背景颜色(myframe部分),这里{}里面为一个字符串,书写风格 “要控制的控件标签或行为{属性:值}”
        self.myframe.setStyleSheet("QWidget{background-color:%s}"%self.color.name())
        hlo=QHBoxLayout(self)    # 水平方向
        hlo.addLayout(vlo)
        hlo.addWidget(self.myframe)

        self.show()

    def setColor(self,p):  # 实际上这里的p是bool值,表示点了按钮后的按钮状态
        # 通过 sender 函数来实现传递参数控件作用
        b=self.sender()
        # print(b.text())  # 这里b.text()为红、绿、蓝三种属性
        # 根据是否选中按钮来决定颜色的值是否拥有
        if p:
            v=255
        else:
            v=0
        # 根据按钮的文字来决定哪个参数被赋值为255或者0
        if b.text()=="红":
            self.color.setRed(v)
        elif b.text()=="绿":
            self.color.setGreen(v)
        elif b.text()=="蓝":
            self.color.setBlue(v)
        # color.name为16进制存储
        self.myframe.setStyleSheet("QWidget{background-color:%s}" % self.color.name())

if __name__ == "__main__":
    app=QApplication(sys.argv)
    mc=Myclass()
    app.exec_()


2.10 PyQt5单行文本框QLineEdit文本改变事件

其为单行文本框,对应于文本改变事件textChanged,结合信号槽.
标签使用QLabel,默认宽度为固定的.当标签文本内容超过标签宽度的显示区域时,超出部分的内容就会进行遮挡,此时我们可以考虑让标签的内容进行区域自适应,使用adjustsize.
完整代码如下。

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

class Myclass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("美丽的世界")
        self.setGeometry(400,100,400,300)
        self.lbl=QLabel("显示区",self)
        self.lbl.move(50,50)

        le=QLineEdit(self)
        # 注意信号在传参时要将小括号改为中括号
        le.textChanged[str].connect(self.ljmTxt)
        self.show()

    def ljmTxt(self,s):
        # print(s)  # 信号一旦改变就会整串的输出最新文本
        self.lbl.setText(s)
        self.lbl.adjustSize()

if __name__=="__main__":
    app=QApplication(sys.argv)
    mc=Myclass()
    app.exec_()

2.11 PyQt5复选框QCheckBox控件状态事件应用

状态复选框应用.
我们案例中的Qframe实际上本质是一个QWidget.
使用stateChanged信号,可以传递整型参数.
通过self对象的sender方法就可以区分不同控件传过来的参数.
完整代码。

import sys
from PyQt5.QtWidgets import QApplication,QWidget,Qframe,QCheckBox
from PyQt5.QtCore import Qt

class Myclass(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle("美丽的世界")
        self.setGeometry(400,100,400,300)

        myframel=Qframe(self) # 外面是一个frame,里面有两个按钮
        self.ck1=QCheckBox("跳舞",myframel)  # 设置复选框
        self.ck1.stateChanged[int].connect(self.myState)  # 此时当选中时传入2,取消勾选时传入0
        self.ck2=QCheckBox("唱歌",myframel)
        self.ck2.stateChanged[int].connect(self.myState)
        self.ck2.move(0,30)
        myframel.move(50,50)  # 两个同时移动
        self.show()

    def myState(self,a):
        s=self.sender()  # s实为不同的地址
        if a==Qt.Checked:  # 写成 Qt.Checked能更方便阅读代码
            print(s.text())
        else:
            print("取消"+s.text())

if __name__=="__main__":
    app=QApplication(sys.argv)
    mc=Myclass()
    app.exec_()


注:Qt中有很多枚举类表示,比如该案例中选中复选框使用2对应表示Qt.Checked,写成枚举类型的好处是方便我们阅读代码.

2.12 PyQt5滑块控件QSlider应用
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/286259.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号