pyQt python制作图形化界面

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

使用pyqt需要先安装QT4。目前QT4最高支持到python3.4。QT5存在太多兼容性BUG,我们就不使用了。当然QT5下设计好的ui界面qt4下一样能用。

目录:

1、安装

2、设计窗口

3、添加控件

4、ui转py

5、py中显示窗口

6、按钮响应

7、耗时任务与多线程与信号

 

1、安装。

本文使用python3.4+qt4使用。其他版本请下载对应版本安装。方法一样!

下载链接&附python:https://pan.baidu.com/s/101lI6aDVegVqiZNphJY-EQ 密码:hu72

注意:python安装包建议还是跟电脑位数一样,一般建议都是x64位的。qt版本则必须与python版本对应,例如python27x64位的,那么安装的qt4必须是带 python27x64位的。如果这里没有适合你使用的qt4版本,可以百度下例如"pyqt4 2.7 x64"这样搜索。

QT4安装到python3.4的安装目录下,我就不多说了。

 

2、设计窗口

可以在 开始->所有程序->pyQt4 GPL v4....->Designer 打开qt设计师。

widget、mainwindow和dialog有什么区别,可以参考文献。https://www.cnblogs.com/584709796-qq-com/p/4949410.html

我简单说明一下:

mainwindow      是主窗口,有默认的菜单栏等。

widget                是对话框,一般用于简单提示。例如,简单的yes/no选择。

Dialog                也是对话框,一般用于有提示的多内容窗口。例如,弹出来的要求注册、登录、sn码注册等。

mainwindow 必须使用QMainWindow()初始化才能显示。

widget和Dialog 可以用QWidget ()或QMainWindow()初始化就能显示。

我选用mainwindow初始化了一个窗口。

【ps我个人更习喜欢widget。因为什么都没有可以让我随心所欲的设计】

 

3、添加控件

qt设计师非常方便,只需要拖拽就能加入新控件。双击控件能直接修改显示文本。右下角objectName能修改控件名。

我删除了菜单栏(窗口最上面右键删除),删除了状态栏(窗口最下面右键删除),并添加了一个名叫runbutton的按钮,和名叫labelstatus的文本框。

保存为ui_mainwindow.ui文件。

#ui_mainwindow.ui(代码可在后续的git中找到)【这是设计师自动生成的,大家不用理解,也不要修改哦】



 MainWindow
 
  
   
    0
    0
    381
    196
   
  
  
   主窗口
  
  
   
    
     
      40
      90
      75
      23
     
    
    
     运行
    
   
   
    
     
      190
      92
      54
      20
     
    
    
     待命
    
   
  
 
 
 

 

4、ui转py

html代码我们python无法使用。于是需要转成.py的文件。

我们在这ui所在文件夹,在cmd中运行下面的命令即可。【可以保存为.bat文件方便直接双击使用】

pyuic4.bat ui_mainwindow.ui -o ui_mainwindow.py

pyuic4.bat 是pyqt自带工具

xxxx.ui是你的ui文件名

-o xxxx.py 是指定转成py的文件名

如果你跟我一样有多个python和多个qt,我建议使用绝对路径运行。结果虽然没差异,但我还是追求严谨。

C:\Python34\Lib\site-packages\PyQt4\pyuic4.bat ui_mainwindow.ui -o ui_mainwindow.py

 

5、py中显示窗口

新建一个main.py文件。PYTHON_BAN的作用是识别运行环境。我们py3,可以直接赋值PYTHON_BAN=3。为什么这么写,可以参考我的另一篇博客。https://my.oschina.net/jacky326/blog/1838149

#main5.py
#-*-coding:utf-8-*-
from BASECLASS import PYTHON_BAN
import sys
if PYTHON_BAN in (2,):
    #在py2下,这是为了处理中文乱码问题。py3下官方修复就不要这样处理了。
    reload(sys)
    sys.setdefaultencoding('utf-8')
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
from ui_mainwindow import Ui_MainWindow

class Dialog(QObject,Ui_MainWindow):
    def __init__(self):
        Ui_MainWindow.__init__(self)
        QObject.__init__(self)
        #如果是widget类型
        #self.widget=QWidget()
        #如果是mainwindow类型
        self.widget = QMainWindow()
        self.setupUi(self.widget)
        self.widget.show()
        
if __name__ == '__main__':
    app=QApplication(sys.argv)  
    ui = Dialog()
    sys.exit(app.exec_())  

直接运行就能显示了。

 

6、按钮响应

我们为按钮添加响应。需要先在类中添加一个按钮响应的函数(名字可自定)。然后在__init__结尾绑定按钮点击时的响应格式是 self.xxxxx按钮.clicked.connect(self.xxxxxx函数)

例如self.runbutton.clicked.connect(self.runbutton_down)

我比较建议把这样绑定按钮的逻辑放在一个单独的函数里,在__init__后立刻调用,当然这仅仅是为了美观。

#main.py
#-*-coding:utf-8-*-
from BASECLASS import PYTHON_BAN
import sys
if PYTHON_BAN in (2,):
    #在py2下,这是为了处理中文乱码问题。py3下官方修复就不要这样处理了。
    reload(sys)
    sys.setdefaultencoding('utf-8')
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import time
from ui_mainwindow import Ui_MainWindow

class Dialog(QObject,Ui_MainWindow):
    def __init__(self):
        Ui_MainWindow.__init__(self)
        QObject.__init__(self)
        #如果是widget类型
        #self.widget=QWidget()
        #如果是mainwindow类型
        self.widget = QMainWindow()
        self.setupUi(self.widget)
        self.widget.show()
        self._band_()
    def _band_(self):
        self.runbutton.clicked.connect(self.runbutton_down)
    def runbutton_down(self):
        self.labelstatus.setText(u'运行中')
        #time.sleep(5)
        self.labelstatus.setText(u'完成')
        
if __name__ == '__main__':
    app=QApplication(sys.argv)  
    ui = Dialog()
    sys.exit(app.exec_())  

简单任务瞬间完成!!!

 

7、耗时任务与多线程与信号

可是这样是有问题的哦!!!假如,我们点击按钮会执行一个复杂任务,完成后提示完成。解除注释time.sleep(5)试试。会发现运行时,窗口无法拖动等,进入“无响应”的状态!

立刻想到这是因为主线程卡主了,最佳方案就是经典的多线程!

#main7.py
#-*-coding:utf-8-*-
from BASECLASS import PYTHON_BAN
import sys
if PYTHON_BAN in (2,):
    #在py2下,这是为了处理中文乱码问题。py3下官方修复就不要这样处理了。
    reload(sys)
    sys.setdefaultencoding('utf-8')
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import time,threading
#from ui_widget import Ui_MainWindow
from ui_mainwindow import Ui_MainWindow

class Dialog(QObject,Ui_MainWindow):
    def __init__(self):
        Ui_MainWindow.__init__(self)
        QObject.__init__(self)
        #如果是widget类型
        #self.widget=QWidget()
        #如果是mainwindow类型
        self.widget = QMainWindow()
        self.setupUi(self.widget)
        self.widget.show()
        self._band_()
    def _band_(self):
        self.runbutton.clicked.connect(self.runbutton_down)
    def runbutton_down(self):
        t = threading.Thread(target=self.runbutton_down_runner)
        t.start()
    def runbutton_down_runner(self):
        self.labelstatus.setText(u'运行中')
        time.sleep(5)
        self.labelstatus.setText(u'完成')
        
if __name__ == '__main__':
    app=QApplication(sys.argv)  
    ui = Dialog()
    sys.exit(app.exec_())  

这样基本就可以了。【嗯?居然可以了?】

好吧。如果可以了就可喜可贺完成吧

失败就继续看吧。

我还是提一下吧,我以前刚学习pyqt的时候,在子线程里改变主线程的控件是会报错的。对!会报错!报错的大意是“控件不能在其他线程改变”。原本写到这应该就出现异常了。也许我以前用的qt有bug或者其他的吧。可以用就最好了,不可用就继续下去。

(假如)报错“控件不能在其他线程改变”,那么我们就需要用到QT的信号

信号的初始化时要做的有两点:①信号必须在__init__运行之前就声明信号建议全大写,这是C++编程时的编写规范,我希望沿用。例如:SHOW_STATUS = pyqtSignal(str)。

信号传入参数可以是任意多的数据类型(也可以空白)。假如我需要传入两个int和一个字符串,可以是SHOW_STATUS = pyqtSignal(int,int,str)。

②信号需要在使用前绑定调用函数这可以是多个函数,并且不会相互覆盖,而是同时执行。【但我还是不建议这样使用,我建议一个信号绑定一个函数,以免混乱】这意味着,信号不能在运行中解绑。self.SHOW_STATUS.connect(self.show_status)绑定。

调用时使用self.SHOW_STATUS.emit(u'完成')即可发送信号。【发送信号】

#main7.py
#-*-coding:utf-8-*-
from BASECLASS import PYTHON_BAN
import sys
if PYTHON_BAN in (2,):
    #在py2下,这是为了处理中文乱码问题。py3下官方修复就不要这样处理了。
    reload(sys)
    sys.setdefaultencoding('utf-8')
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import time,threading
from ui_widget import Ui_MainWindow
#from ui_mainwindow import Ui_MainWindow

class Dialog(QObject,Ui_MainWindow):
    SHOW_STATUS = pyqtSignal(str)
    def __init__(self):
        Ui_MainWindow.__init__(self)
        QObject.__init__(self)
        #如果是widget类型
        #self.widget=QWidget()
        #如果是mainwindow类型
        self.widget = QMainWindow()
        self.setupUi(self.widget)
        self.widget.show()
        self._band_()
    def _band_(self):
        self.runbutton.clicked.connect(self.runbutton_down)
        self.SHOW_STATUS.connect(self.show_status)
        self.SHOW_STATUS.connect(self.x)
    def runbutton_down(self):
        t = threading.Thread(target=self.runbutton_down_runner)
        t.start()
    def runbutton_down_runner(self):
        #self.labelstatus.setText(u'运行中')
        self.SHOW_STATUS.emit(u'运行中')
        time.sleep(5)
        #self.labelstatus.setText(u'完成')
        self.SHOW_STATUS.emit(u'完成')
    def x(self):
        print('order!')
    def show_status(self,message):
        self.labelstatus.setText(message)
        
if __name__ == '__main__':
    app=QApplication(sys.argv)  
    ui = Dialog()
    sys.exit(app.exec_())  

EX:

最后附上main.py真正完整正确的代码。

#main7.py
#-*-coding:utf-8-*-
from BASECLASS import PYTHON_BAN
import sys
if PYTHON_BAN in (2,):
    #在py2下,这是为了处理中文乱码问题。py3下官方修复就不要这样处理了。
    reload(sys)
    sys.setdefaultencoding('utf-8')
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtWebKit import *
import time,threading
#from ui_widget import Ui_MainWindow
from ui_mainwindow import Ui_MainWindow

class Dialog(QObject,Ui_MainWindow):
    SHOW_STATUS = pyqtSignal(str)
    def __init__(self):
        Ui_MainWindow.__init__(self)
        QObject.__init__(self)
        #如果是widget类型
        #self.widget=QWidget()
        #如果是mainwindow类型
        #self.widget = QMainWindow()
        self.setupUi(self.widget)
        self.widget.show()
        self._band_()
    def _band_(self):
        self.runbutton.clicked.connect(self.runbutton_down)
        self.SHOW_STATUS.connect(self.show_status)
    def runbutton_down(self):
        t = threading.Thread(target=self.runbutton_down_runner)
        t.start()
    def runbutton_down_runner(self):
        self.SHOW_STATUS.emit(u'运行中')
        time.sleep(5)
        self.SHOW_STATUS.emit(u'完成')
    def show_status(self,message):
        self.labelstatus.setText(message)
        
if __name__ == '__main__':
    app=QApplication(sys.argv)  
    ui = Dialog()
    sys.exit(app.exec_())  

代码:

git: https://gitee.com/kid0/pyqt_show.git

百度云:链接:https://pan.baidu.com/s/1CxYipjfeJCkyyuLbyK_WFg 密码:klfd

总结:

其实本来是要想说qt的信号重要性的,但似乎新版不会出现这问题。所以最后还是简要的说了下。以上是python+qt4的图形化界面显示的模板。

转载于:https://my.oschina.net/jacky326/blog/1842966

你可能感兴趣的:(pyQt python制作图形化界面)