簡體   English   中英

QFileDialog - PyQt4/PyQt5/PySide 之間的差異

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM