在Python 2.6中使用QTDesigner与PyQT
我刚开始学习Python,打算自学图形用户界面(GUI)编程,计划使用PyQT4.7和Python 2.6。
我刚从PyQT网站下载了整个PyQT/QT4包(包括QTDesigner),看起来QTDesigner对于新手来说非常好用,因为你可以看到每个控件的所有属性、默认值等,并且可以直观地编辑这些属性。不过,PyQT似乎没有让QTDesigner和PyQT直接整合在一起,也就是说,QTDesigner生成的代码不能直接和PyQT的Python代码生成脚本配合使用。
比如,当我点击“查看代码”时,它试图运行一个叫做(uic)的C++脚本,而不是pyuic.py脚本等等。
有没有办法让QTDesigner和PyQT更紧密地结合,以便像在C++中那样实时生成代码呢?
如果没有,那是不是意味着我必须在我的Python开发环境中手动编写整个QT GUI,还要查找每个控件的文档和模板代码?(这听起来效率低下,也不太优雅,相比之下,QTDesigner和Python的结合会更好)。
使用Designer和PyQT的常规工具链和生产流程是什么样的?(如果没有直接的整合,Python和PyQT的用户是不是就完全跳过QTDesigner,手动编写所有QT GUI代码呢?)
如果有其他建议或者提示给PyQT的新手,我会非常感激。谢谢!
顺便说一下,我知道可能会有人告诉我直接手动编写所有QT UI代码,但如果我在学习时使用Designer,请提供一种方法让我更容易地学习,谢谢!
4 个回答
你可以在控制台直接运行 pyuic
(或者说 pyuic4
)。你可以用设计工具来创建你的图形用户界面(GUI),就像用C++一样。
顺便说一下:我为我的应用程序手动写了所有的图形界面代码(大约1万行)。我其实不太喜欢用图形界面设计工具,也不喜欢处理那些自动生成的代码,因为当你需要修改一些东西的时候会很麻烦。
我做的事情是创建了一个自己的uic可执行文件,它是pyuic.py脚本的一个包装。
你需要...
获取并安装 py2exe
在下面的uic.py代码中替换PYTHON_PATH
编辑site-packages\PyQt4中的qt.conf文件,并设置Binaries=路径,指向生成的uic可执行文件所在的文件夹。
将uic.py和setup.py放在同一个文件夹里
在命令提示符中导航到包含setup.py和uic.py的文件夹,然后运行以下命令 "python setup.py py2exe"。
//----uic.py
#uic.py
import subprocess
import sys
args = ""
for arg in sys.argv:
if sys.argv[0] != arg:
args += arg + " "
# Start pyuic.py script
command = 'python %PYTHON_PATH%\\PyQt4\\uic\\pyuic.py '+ args
out = ''
child = subprocess.Popen(command, shell=True, stderr=subprocess.PIPE)
complete = False
while True:
out = child.stderr.read(1)
if out == '' and child.poll() != None:
break
if out != '':
sys.stdout.write(out)
sys.stdout.flush()
//----- setup.py
#setup.py
from distutils.core import setup
import py2exe
setup(windows=[{"script":"uic.py"}], options={"py2exe" : {"includes" : ["sip", "PyQt4.QtCore"]}})
我开始写我的第一个PyQT应用程序(PyQT主要用来处理图形界面),看起来一个不错的工具组合是:使用QtDesigner来生成.ui文件和管理资源,再加上一个可以设置QtDesigner进行编辑的IDE。我用的是Eclipse,因为它可以高度自定义。
你可以在应用程序启动时、设置时或其他任何时候按需编译你的.qrc和.ui文件,方法大致如下:
os.system("pyrcc4.exe -o ui/images_rc.py ui/images/images.qrc")
uic.compileUiDir(appDir + '/ui', True)
然后可以这样使用生成的类:
class MyMainWindow(QtGui.QMainWindow):
def __init__(self, owner):
QtGui.QMainWindow.__init__(self)
# 'Ui_MyMainWindow' is the class, that was generated by uic,
# naming convention is: 'Ui_' plus the name of root widget in designer
self.ui = Ui_MyMainWindow()
self.ui.setupUi(self)
或者你可以在容器初始化时直接加载.ui文件:
QtGui.QMainWindow.__init__(self)
self.ui = None
uic.loadUi('MyMainWindowUI.ui', self.ui)
#now you have the instance of Ui_MyMainWindow in self.ui too, as above
注意,我在.ui文件名后加了UI后缀,这是为了避免名字冲突,因为通过uic生成的.py文件的名字并不是以'Ui_'开头的类名,而只是根部件的名字。
还有一点要注意:在生成文件的末尾,uic会放入'import %.qrc name%_rc'这行代码(默认是import images_rc),所以在使用pyrcc4时要留意这一点。
这种方法非常灵活,可以帮你省去很多无聊的界面编码工作;但你仍然可以在MyMainWindow.ui属性中进行一些微调,Ui_MyMainWindow的实例就在这里;这样也避免了不必要的继承。就我个人而言,我在MyMainWindow中创建了_connectSlots和_initIntefrace方法来处理一些设计器无法做到的事情。
不过我还是要说,自己写界面代码是个不错的选择,因为uic生成的代码实在是太丑了。我更喜欢用loadUi()直接加载.ui文件,原因就是这样 :) 如果你有很多自定义的PyQT控件,把它们放进QtDesigner里真的是太无聊了……