[英]Is there a difference between QFileDialog strings in PyQt4 and PyQt5?
[英]QFileDialog - differences between PyQt4/PyQt5/PySide
我一直在閱讀關於使用 Python 和 QT 進行快速 GUI 編程的 Summerfields 書(更准確地說是 PyQt),但 2007 年的書使用了 4.x 版,我正在嘗試使用當前版本(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
應該返回什么。
我錯過了什么?
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
的指針,這意味着它可以。
最初,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
的簽名getSaveFileName
為返回元組會造成太多破壞,因此添加了getSaveFileNameAndFilter
函數作為臨時妥協。
PyQt5 沒有這樣的限制(它甚至不再需要提供QString
)。 所以終於有可能做正確的事情(從 Python 的角度來看)並且只從getSaveFileName
返回一個元組。 這個原則現在普遍適用:如果您使用 PyQt5,並且您在 Qt 文檔中看到一個修改其參數的函數,您總是可以期望返回一個元組。
(PS:PySide 的用戶——它比 PyQt 年輕得多——從來不必處理這些問題。對他們來說,靜態QFileDialog
函數總是做正確的事情)。
QFileDialog
這些方法看起來有點特別,因為 PyQt 已經實現了自己的方法,而不是直接包裝 Qt 方法。
首先,PyQt5 QFileDialog.getSaveFileName()
方法實現的行為QFileDialog.getSaveFileNameAndFilter()
方法從PyQt4的( 源)。 其次,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 類/方法在解碼時不會如此混亂!
使用以下語法(添加昏迷和下划線)可以繞過解決 getSaveFileName 方法(使用 PyQt5)的“元組問題”:
fname, _ = QFileDialog.getSaveFileName(self,
"Image Changer - Save Image", fname,
"Image files ({})".format(" ".join(formats)))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.