2017-04-07 28 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,但这确实是一个巨大而几乎毫无意义的维护负担。通过向导执行此操作的唯一好处是,它可以正确地从不具有特殊属性的页面中注册字段。无论哪种方式,你都赢得了这个赏金。 –

相关问题