本文转自:http://www.52ij.com/jishu/432.html,转载请保留链接
之前说了一下PyQt-Designer生成UI文件转为py文件的方法.波哥试了一下,在装配到自己工程的时候卡住了.我那篇笔记最后也说了,要想用,还有点需要改动的.今天趁自测项目的空闲,写一下.
先随便做一个UI,这里我直接拖了一个日历控件过来.
生成py代码,之前说过的.
新建一个工程.新建一个src包,会自动生成一个__init__.py.
把test.py,就是那个ui生成的代码拷进来.
下面是没有经过改动的代码,需要注意的几个地方,做了标记.
框起来的(object)表示这个类继承自object.这里修改成QtGui.QMainWindow.至于原因,也很简单.在我做实验的时候,发现生成的两个方法
setupUi和retranslateUi需要传入一个参数,就是上图红线画出来的,MainWindow,我就想,不如让这个类本身继承自QMainWindow,那么在调用自动生成的方法来初始化窗口的时候,自需要把它本身,也就是self传进去即可.
改动之后的代码如下,加了一个__init__方法,这个在一会儿创建窗口对象的时候会自动调用,类似java的构造器.
在__init__里,先调用了父类QMainWindow的构造方法,然后调用了自动生成的两个方法,注意,传的是self,因为他自己已经是QMainWindow了.
这里需要调用super(xxx,yyy).__init__(),其实是一点点试出来的,一开始按照java的习惯去做,没有这个调用,结果报错了,才发现它不会自动调用父类构造方法.
下面,在自动生成的那个__init__.py文件里,写入如下代码.
第一句是创建了一个PyQt封装的QApplication对象,创建的时候,把系统参数传进去了.顾名思义,这一句创建了一个应用程序对象
第二句是创建一个我们生成的那个窗口
第三句是显示窗口
第四句是把应用程序对象的exec_()方法的返回值传给sys.exit().当点击关闭窗口的时候,exec_()方法会给sys.exit()一个返回值,让它关闭程序
这里多说一句,上面的分析可能有不妥的地方,再深入学习之后,回过来看的时候会改.
另外,写完第四点,我灵光一闪,觉得app.exec_()这个方法,应该是一个阻塞方法,它维持着整个程序的运行,当接收到退出操作的时候,才会返回一个值,然后sys.exit()接到返回值让整个程序退出.
原来这就是我一直在想的,pyqt没有tkinter里的.mainloop()类似方法,怎么让程序一直跑起来的呢.原来藏这么深...
我换了好几个UI,做了好几个小工具,所以,上面的步骤重复了好几次,但是在写前两遍的时候,我并没有想这么多,只是觉得这样能跑起来.知道今天,再一次尝试,才有一点点深入的体会.所以,多用,多思考真的很重要啊...
在这个文件上右键run一下,跑起来了...
代码贴出来:
src/__init__.py from PyQt4 import QtCore, QtGui import sys import test app=QtGui.QApplication(sys.argv) win=test.Ui_MainWindow() win.show() sys.exit(app.exec_()) src/test.py # -*- coding: utf-8 -*- # Form implementation generated from reading ui file 'D:\Program Files\Python2.7\Lib\site-packages\PyQt4\test.ui' # # Created: Mon Mar 04 13:03:57 2013 # by: PyQt4 UI code generator 4.9.6 # # WARNING! All changes made in this file will be lost! from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: def _fromUtf8(s): return s try: _encoding = QtGui.QApplication.UnicodeUTF8 def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig, _encoding) except AttributeError: def _translate(context, text, disambig): return QtGui.QApplication.translate(context, text, disambig) class Ui_MainWindow(QtGui.QMainWindow): def __init__(self): super(Ui_MainWindow,self).__init__() self.setupUi(self); self.retranslateUi(self) def setupUi(self, MainWindow): MainWindow.setObjectName(_fromUtf8("MainWindow")) MainWindow.resize(440, 200) self.centralwidget = QtGui.QWidget(MainWindow) self.centralwidget.setObjectName(_fromUtf8("centralwidget")) self.calendarWidget = QtGui.QCalendarWidget(self.centralwidget) self.calendarWidget.setGeometry(QtCore.QRect(0, 0, 441, 181)) self.calendarWidget.setObjectName(_fromUtf8("calendarWidget")) MainWindow.setCentralWidget(self.centralwidget) self.statusbar = QtGui.QStatusBar(MainWindow) self.statusbar.setObjectName(_fromUtf8("statusbar")) MainWindow.setStatusBar(self.statusbar) self.retranslateUi(MainWindow) QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) |
又到了结尾,这个界面跑起来了,但是点上去是没有反应的.怎么把回调函数(事件处理函数)安上去,这个,下次再写,涉及到pyqt的信号和槽.
总结:
1. 创建scr 文件夹,将目标ui 文件保存到此目录,复制"C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py" 到该目录,新建transform.bat 文件,在里面写上 pyuic.py -o test.py test.ui,双击运行此文件产生test.py
2. 打开test.py 修改里面class 的参数为QtGui.QMainWindow, 并定义构造函数:
def __init__(self):
self.super(Ui_MainWindow,self).__init__()
self.setupUi(self)
self.retranslateUi(self)
3. 在src 中创建包标志文件__init__.py, 打开在里面写上:
from PyQt4 import QtCore, QtGui
import sys
import test
app = QtCore.QApplication(sys,argv)
win = test.Ui_MainWindow()
win = show()
sys.exit(app_exec())