2017-04-07 112 views
0

我正在研究一個簡單的QWizard,它在其頁面上顯示一些單選按鈕。給定頁面上的按鈕都是同一個QButtonGroup的一部分。該頁面註冊爲自己的自定義字段的基礎上,按鈕組中選擇:PyQt獲取QWizard中所有註冊字段的集合

class Page1(QWizardPage): 
    selectionChanged = pyqtSignal('QString') 

    def __init__(self, name): 
     self.group = QButtonGroup() 
     self.group.addButton(QRadioButton("a")) 
     self.group.addButton(QRadioButton("b")) 
     self.group.addButton(QRadioButton("c")) 
     self.registerField(name, self, 'selection', self.selectionChanged) 

    @pyqtProperty('QString') 
    def selection(self): 
     checkedButton = self.group.checkedButton() 
     return checkedButton.text() if checkedButton else None 

    def nextId(self): return -1 

我最終註冊self爲包含字段屬性,只是因爲QButtonGroup不是QWidget小部件。所有其他頁面看起來非常像這樣(我實際上使用基類來完成所有常見工作,而這只是一個簡單的例子)。

我希望能夠獲得QWizard中所有註冊字段的列表。我還沒有發現Qt提供任何方法讓我做到這一點,所以我通過覆蓋每一頁的registerField方法的行爲,以及嚮導的addPage做了變通方法:

def registerField(self, name, *args, **kwargs): 
    self.field_names.add(name) 
    if self.wizard() is not None: 
     self.wizard().field_names.add(name) 
    super().registerField(name, *args, **kwargs) 

def addPage(self, page, *args, **kwargs): 
    self.field_names.union(page.field_names) 
    return super().addPage(page, *args, **kwargs) 

然後,我可以使用父QWizardfield_set屬性與QWizard.field結合來訪問所有值。這似乎有點多餘,因此是不必要的。 Qt中有一種方法可以訪問完整的字段集合嗎?relevant section in the documentation沒有提及任何內容,但是有很多其他細節沒有提及,所以這不是很明顯。

我的假設是,如果存在的話,PyQt4的功能與PyQt5的相同。如果不是的話,我會更喜歡PyQt5的答案,因爲那是我目前使用的。

回答

1

你說如果答案是否定的,它必須是「非常有說服力」。您承認文檔中沒有提及您需要的功能,我將指出QWizard的公共功能列表中沒有此類功能。因此,所需的功能(如果它完全存在的話)是未記錄的。對我而言,單憑這一考慮將是一個「非常令人信服」的理由,不會使用它。 Qt的下一個版本可能沒有這個功能,或者它可能不會以同樣的方式工作。

同時你有一個可接受的解決方案,包含八行直接的python代碼。鑑於這種選擇和調用一個未公開的函數(如果你能找到它),python解決方案在所有實際方面都大大優越。

但是,您的Python代碼存在潛在的問題。您可以覆蓋功能QWizard.addPage,但還有另一個功能QWizard.removePage,應該可能也會覆蓋它。我更喜歡的另一種方法是,不要將field_names存儲在QWizard中,而只存儲在各個頁面中。添加方法QWizard動態地建立了一套所有當前FIELD_NAMES的:

def all_field_names(self): 
    return {s for page_id in self.pageIds() for s in self.page(page_id).field_names} 

[我沒有測試此功能的一個很好的方式,但我認爲你的想法現在你刪除重寫方法QWizard.addPage,從QWizard中刪除變量field_names,並刪除中間兩行register_field。現在你只有五行Python代碼,無論頁面被添加或刪除如何,它都可以工作。而且你不再將字段名稱存儲在兩個地方。

對於它的價值,每當我面對使用Qt的功能或基本的Python功能之間進行選擇,我永遠向着Python的傾斜。我使用線程而不是QThreads,線程化鎖定和定時器而不是Qt等價物,Python方法對象和回調,而不是自定義槽和信號。 Qt是爲C++程序員編寫的,這通常意味着它不像我所希望的那樣「pythonic」。

+0

非常有說服力,據我很擔心。我絕對喜歡你的解決方案。我真正的代碼覆蓋了setPage,addPage和removePage,但這確實是一個巨大而幾乎毫無意義的維護負擔。通過嚮導執行此操作的唯一好處是,它可以正確地從不具有特殊屬性的頁面中註冊字段。無論哪種方式,你都贏得了這個賞金。 –