Python:Pyqt5相关 安装-应用-简单使用

2023-03-10 13:42:32 浏览数 (1)

从开始有想法学习python到现在也大概半年了,断断续续的一直再看,主要是:廖雪峰Python链接如下:

https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

一些python基础语法,安装都从上边学习,到目前为止,基础语法学习完成了,应用还得多写代码,编辑工具使用的Notpad ,IO,多线程,Web,网络都还没看,随后估计会看网络和IO,Web有兴趣再看了。

最近几天在弄,Python图形化界面,由于之前拿Qt开发,习惯了信号与槽的消息机制,所以知道有pyqt之后就开始研究了。Python的图形化界面库还挺多的,我只说说我接触过的两个。TKinter和Pyqt5。

tkinter库: Python自带库,放一个我写的小demo

调用:

代码语言:javascript复制
from tkinter import *
import tkinter.messagebox as messagebox

类:

代码语言:javascript复制
class Application(Frame):
    def __init__(self,master = None):
        Frame.__init__(self,master)
        self.pack()
        self.createWidgets()

    def input_One(self,num):
        print("Input",num)  

    def createWidgets(self):
        self.nameInput = Entry(self)
        self.nameInput.pack(side =  TOP,padx=10,pady=10)
        self.atButton  = Button(self,text='Hello',bg = "red",fg = "black",command = self.hello)
        self.atButton.pack()
        self.m_photo = PhotoImage(file = "D:Python\66logo.png")
        self.m_label = Label(self,text = "Python学习",font = ('Arial', 15),bg= "blue",fg = "red",width = 240,height = 200,compound = CENTER)
        self.m_label.pack(side = RIGHT,padx= 60,pady = 60)      
        self.image_label = Label(self.m_label,image = self.m_photo).grid(row = 0)
    #   self.image_label.place(in_ = self.m_label,relx = 0.5,rely = 0.5,anchor =CENTER,x =-58,y=-55)
    #   self.image_label.pack(side = TOP,padx = 20,pady=20)
    #   ax = -58
    #   ay = -55
        row_x = 1
        row_y = 1
        for i in range(1,10):           
            if i <=3:
                if i ==1:
    #               ax = -58
                    row_y = 1
                else:
    #               ax  = 20
                    row_y =1
    #           ay = -35
                row_x = 1
            elif i > 3 and i<=6:
                if i == 4:
    #               ax = -58
                    row_y = 1
                else:
    #               ax =20
                    row_y  =1
    #           ay = -5
                row_x = 2
            elif i>6 and i<=9:
                if i == 7:
    #               ax = -58
                    row_y = 1
                else:
    #               ax =20
                    row_y  = 1
    #           ay = 25
                row_x = 3
            print(i)
            self.One_Btn = Button(self.m_label,text=str(i),command = lambda:self.input_One(i),width = 2,height = 1).grid(row=row_x,column = row_y )
    #   self.Two_Btn = Button(self,text="two").grid(row = 4,column)
            #self.One_Btn.place(in_ = self.m_label,relx = 0.5,rely = 0.5,anchor =CENTER,x =ax,y=ay)

    def hello(self):
        name = self.nameInput.get() or 'world'
        if name == 'quit':
            print('quit')
        messagebox.showinfo('Message','hello,%s' % name)

类的部分不做释意了,就说一下思路,按照教程写了一个基础UI界面,Entry,然后按钮弹出提示框,如果有输入则提示框显示“Hello,str”,否则提示“Hello,world”。后来,在Label里边,写了显示文字,显示图片。然后准备做一个计算器。

这时候发现了问题,或者是我接触时间短不知道怎么解决。界面布局,tkinter有三种,pack(),grid(),place()。布局分类不能像Qt一样,自由设置Label内部图片显示位置,坐标,写法比较僵硬。如果Label设置为父控件,子控件在放置Label或者其他,为了设置图片位置,我将图片放置与一个子Laebl中,然后在设置子label在父Label中的位置。尝试了pack(),grid(),place(),说一下对这三个的理解,

代码语言:javascript复制
pack(),侧重于方位布局,LEFT,RIGHT,TOP等,然后可以通过padx,pady设置偏离位置。

grid(),模块自动计算行列位置,将窗口或者父控件按比列划分,类似于Excel表格。可以自由设置行列位置,区块类布局比较方便。

place(),用于设置绝对位置。

感觉对与布局的细节设置不是很方便,比较繁琐。

另外一个,消息机制,目前我还没弄懂。比如说:button的按键响应事件

代码语言:javascript复制
self.One_Btn = Button(self.m_label,text=str(i),command = lambda:self.input_One(i),width = 2,height = 1).grid(row=row_x,column = row_y )

其中:按键响应函数如下command = lambda:self.input_One(i)按钮,执行input_One(i)函数时,本意是这样,通过for循环,创建好9个按钮,都绑定input_One(i),执行函数时,每个传参应该都不一样,我想自动获取按键对应的编号,暂时没有找到函数获取。按理说,每一次绑定的执行函数时,i的值都是唯一确定,但是打印消息时,发现i的值,临时获取,最后一个i的值,暂时没想到解决方法。 界面调用部分:

代码语言:javascript复制
app = Application()
app.master.geometry('400x300')
app.master.resizable(width=False, height=False)
app.master.title('Hello World')
app.mainloop()

Pyqt5:安装

python都默认安装好,环境也都配置好。

代码语言:javascript复制
**error:This application failed to start because it could not find or load the Qt platforms plugins**

解决方法:安装python时一定要注意,中文路径的问题,最好不要有中文路径,否则会出现如上错误,安装好pyqt5之后。

安装好python之后,安装pyqt5之前一定要注意,先升级pip,更新到最新版本:

进入cmd:输入命令:

代码语言:javascript复制
python -m pip install --upgrade pip

第二步,升级sip,升级到匹配版本。

命令如下:

代码语言:javascript复制
pip3 uninstall sip

第三步:安装pyqt5

命令行如下:

代码语言:javascript复制
pip3 install pyqt5

等待安装完成后,即可使用pyqt5。其实还有一个问题,因为我是之前一直拿Qt开发,qt库都很全,所以相关工具库我都没有下载配置。如果第一次安装pyqt,则需要安装qttools。

命令如下:

代码语言:javascript复制
pip install PyQt5-tools

全部安装完成后即可使用了。

测试代码:

代码语言:javascript复制
import sys
from PyQt5 import QtWidgets, QtCore
app = QtWidgets.QApplication(sys.argv)
widget = QtWidgets.QWidget()
widget.resize(360, 360)
widget.setWindowTitle("Hello, PyQt5!")
widget.show()
sys.exit(app.exec_())

由于我使用Notpad ,使用Qt设计师建好界面以后,每次更改都要使用如下命令将ui文件改为py文件

代码语言:javascript复制
pyuic5 path/filename.ui -o path/filename.ui

所以写了如下代码,默认ui文件名字和工程文件名除后缀之外相同,且在同一目录下。例如:工程文件名为 code.py,UI文件名为 code.ui。

代码语言:javascript复制
import os
import time
import sys

FileName = os.path.basename(sys.argv[0]) #sys.argv[0] 当前文件的绝对路径 os.path.basename 获得文件名字
FilePath = sys.argv[0].replace(FileName,"") #当前文件路径
UiName = FileName.replace(".py",".ui") #ui文件名字
UiPath = FilePath  UiName    #ui文件路径
Ui_pyName = FilePath "ui.py" #ui.py 文件的绝对路径
FileFlag = os.path.isfile(Ui_pyName) # 判断文件是否存在 1:存在 0:不存在

if FileFlag == 0:
    sys_cmd  = os.popen("pyuic5 " UiPath " -o " Ui_pyName)  #执行cmd命令将 ui文件转为py文件
    time.sleep(1) #延时1S

FileName:工程文件名 code.py

FilePath:工程文件路径 D:python

UiName: UI文件名 code.ui

UiPath:UI文件路径 D:python

Ui_pyname:UI文件转化后的py文件绝对路径 : D:pythonui.py

FileFlag : ui.py文件是否存在标志位,不存在,则新建。

当前判断ui.py是否存在,如果存在则不修改。但是不能够判断py是否为最新文件。 如果想保证每次更新可以改为

代码语言:javascript复制
import os
import time
import sys

FileName = os.path.basename(sys.argv[0]) #sys.argv[0] 当前文件的绝对路径 os.path.basename 获得文件名字
FilePath = sys.argv[0].replace(FileName,"") #当前文件路径
UiName = FileName.replace(".py",".ui") #ui文件名字
UiPath = FilePath  UiName    #ui文件路径
Ui_pyName = FilePath "ui.py" #ui.py 文件的绝对路径
sys_cmd  = os.popen("pyuic5 " UiPath " -o " Ui_pyName)  #执行cmd命令将 ui文件转为py文件

其实随后有一个想法,做一个Notpad 的插件,将如上功能集成到里边,目前正在研究。除去每次繁琐的配置修改。

下边是自己的写的一个Demo,按键显示。

代码语言:javascript复制
import os
import time
import sys

FileName = os.path.basename(sys.argv[0])
FilePath = sys.argv[0].replace(FileName,"")
UiName = FileName.replace(".py",".ui")
UiPath = FilePath  UiName
Ui_pyName = FilePath "ui.py"
FileFlag = os.path.isfile(Ui_pyName)

if FileFlag == 0:
    sys_cmd  = os.popen("pyuic5 " UiPath " -o " Ui_pyName)
    time.sleep(1)

print(Ui_pyName,UiPath,UiName) #打印调试信息

from PyQt5 import QtWidgets, QtGui
from ui import Ui_Form

class m_window(QtWidgets.QWidget,Ui_Form):
    def __init__(self):
        super(m_window,self).__init__()
        self.setupUi(self)
        self.pushButton.clicked.connect(self.hello)  #Qt槽函数连接

def hello(self):    #槽函数    
        self.label.setText("Hello world")

app = QtWidgets.QApplication(sys.argv)
window = m_window();
window.show()
sys.exit(app.exec_())

0 人点赞