我一直在使用Summerfields关于使用Python和QT进行快速GUI编程的书... pyqt是精确的,但2007年的书使用了版本4.something,我试图使用当前版本5.4 .2 ..
我想要弄清楚一些变化,并希望在如何找到东西方面获得一些帮助。以下是文件保存对话框的示例 - 来自书籍:
fname = QFileDialog.getSaveFileName(self,
"Image Changer - Save Image", fname,
"Image files ({})".format(" ".join(formats)))
这不起作用,可能主要是因为在pyqt5中QFileDialog
返回一个元组而不是一个字符串。我能解决这个问题的唯一方法就是试错。 pyqt5文档引用了QT,我真的不明白。
我得到以下工作:
fname = QFileDialog.getSaveFileName(self, 'some text',
"whatever.png", '*.png')
if "." not in fname[0]:
fname[0] += ".png"
self.addRecentFile(fname[0])
self.filename = fname[0]
return self.fileSave()
哇,它有效!但正是因为我正在努力,我才取得任何进展。
我尝试运行python解释器并输入:
from PyQt5.QtWidgets import QFileDialog
help(QFileDialog)
这是(有点)有用,但帮助的语法对我来说没有多大意义,我也看不出getSaveFileName
应该返回什么。这有点乏味 - @ $$的东西。
我错过了什么?
答案 0 :(得分:7)
QFileDialog
的一些静态函数在PyQt中有一个奇怪的历史。如果您不了解这段历史,很难理解各种版本的PyQt之间的差异。
潜在的问题非常简单。在Python中,如果函数需要返回多个值,最常见的解决方案是返回元组。但是在C ++中,这实际上是不可能的,所以通常的解决方案是提供可以修改的参数。
QFileDialog.getSaveFileName
的C ++签名是这样的:
getSaveFileName(
QWidget * parent = 0, const QString & caption = String(),
const QString & dir = QString(), const QString & filter = QString(),
QString * selectedFilter = 0, Options options = 0)
正如您所看到的,四个QString
参数都不一样。前三个是const
,因此不会被函数修改,但selectedFilter
参数会指向QString
,这意味着它可以。{/ p>
最初,PyQt的主要用途是用于C ++原型(而不是开发Python应用程序),因此它的API更忠实于Qt API。这意味着,直到PyQt-4.6,仅从QFileDialog
获取所选过滤器的方式,就是用C ++方式做到这一点,如下所示:
>>> s = QString() # string to be modified
>>> f = QFileDialog.getSaveFileName(None, 'Save', '', 'Img(*.png *.jpg)', s)
>>> print s
Img(*.png *.jpg)
事实上,这仍然可以在PyQt4的当前版本中使用(当然,只要它启用了QString
)。
PyQt4稳步推出了许多变化,这些变化逐渐使得它越来越多地使用Python - 但正如上面的例子所示,这一切都是在没有打破向后兼容性的情况下完成的。当时,更改getSaveFileName
的签名以返回元组会导致太多的破损,因此getSaveFileNameAndFilter
等函数被添加为临时折衷。
PyQt5没有这样的限制(它甚至不需要提供QString
)。因此,最终有可能做正确的事情(从Python的角度来看),并从getSaveFileName
返回一个元组。现在这个原则适用:如果您正在使用PyQt5,并且在Qt文档中看到一个修改其参数的函数,您总是可以期望返回一个元组。
(PS:PySide的用户 - 比PyQt年轻得多 - 从来没有处理过这些问题。对于他们来说,静态QFileDialog
函数总是做正确的事。)
答案 1 :(得分:1)
QFileDialog
的这些方法似乎有点特殊,因为PyQt已经实现了自己的方法而不是直接包装Qt方法。
首先,PyQt5 QFileDialog.getSaveFileName()
方法实现了PyQt4(source)中QFileDialog.getSaveFileNameAndFilter()
方法的行为。其次,PyQt4中的QFileDialog.getSaveFileNameAndFilter()
方法返回(filename, selectedFilter)
(source)元组。
作为参考,PyQt4 QFileDialog.getSaveFileNameAndFilter()
方法的调用签名是
getSaveFileNameAndFilter (QWidget parent = None, QString caption = QString(),
QString directory = QString(), QString filter = QString(),
QString initialFilter = QString(), Options options = 0)
希望这有助于解决任何混乱。大多数PyQt5类/方法都不会令人困惑解码!
答案 2 :(得分:0)
使用以下语法(添加逗号和下划线)可以绕过getSaveFileName方法(使用PyQt5)解决“元组问题”:
fname, _ = QFileDialog.getSaveFileName(self,
"Image Changer - Save Image", fname,
"Image files ({})".format(" ".join(formats)))