在Python 2.6中使用QTDesigner与PyQT

20 投票
4 回答
11425 浏览
提问于 2025-04-15 20:41

我刚开始学习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 个回答

1

你可以在控制台直接运行 pyuic(或者说 pyuic4)。你可以用设计工具来创建你的图形用户界面(GUI),就像用C++一样。

顺便说一下:我为我的应用程序手动写了所有的图形界面代码(大约1万行)。我其实不太喜欢用图形界面设计工具,也不喜欢处理那些自动生成的代码,因为当你需要修改一些东西的时候会很麻烦。

2

我做的事情是创建了一个自己的uic可执行文件,它是pyuic.py脚本的一个包装。

你需要...

  1. 获取并安装 py2exe

  2. 在下面的uic.py代码中替换PYTHON_PATH

  3. 编辑site-packages\PyQt4中的qt.conf文件,并设置Binaries=路径,指向生成的uic可执行文件所在的文件夹。

  4. 将uic.py和setup.py放在同一个文件夹里

  5. 在命令提示符中导航到包含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"]}})
20

我开始写我的第一个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里真的是太无聊了……

撰写回答