PyQt 获取 QWizard 中所有注册字段的集合
PyQt obtaining collection of all registered fields in QWizard
我正在开发一个简单的 QWizard
,它会在其页面上显示一些单选按钮。给定页面上的按钮都是同一 QButtonGroup
的一部分。根据按钮组中的选择,页面本身注册为自定义字段:
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
。所有其他页面看起来都非常像这个(我实际上使用 base class 来完成所有常见的工作,这只是一个最小的例子)。
我希望能够获得 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)
然后我可以使用父QWizard
的field_set
属性结合QWizard.field
to access all the values. This seems a bit redundant and therefore unnecessary. Is there a method in Qt to access the complete collection of fields? The relevant section in the documentation没有提到任何东西,但还有很多其他细节它省略了,所以这不是很有说服力。
我的假设是 PyQt4 和 PyQt5 的功能(如果存在的话)是相同的。如果不是,我更喜欢 PyQt5 的答案,因为那是我目前正在使用的。
你说如果答案是否定的,那肯定是"pretty convincing."你承认文档中没有提到你想要的功能,我要指出的是列表中没有这样的功能QWizard 的 public 个函数。因此,所需的函数(如果存在的话)是 未记录的 。对我来说,仅此考虑就是 "pretty convincing" 不使用它的理由。 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
,去掉中间两行register_field
。现在您只有五行 Python 代码,无论页面如何添加或删除,它们都可以正常工作。而且您不再将字段名称存储在两个地方。
就其价值而言,每当我面临在使用 Qt 功能还是基本 Python 功能之间做出选择时,我总是倾向于 Python。我使用线程而不是 QThreads,线程锁和定时器而不是 Qt 等价物,Python 方法对象和回调而不是自定义插槽和信号。 Qt 是为 C++ 程序员编写的,这通常意味着它并不像我想要的那样 "pythonic"。
我正在开发一个简单的 QWizard
,它会在其页面上显示一些单选按钮。给定页面上的按钮都是同一 QButtonGroup
的一部分。根据按钮组中的选择,页面本身注册为自定义字段:
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
。所有其他页面看起来都非常像这个(我实际上使用 base class 来完成所有常见的工作,这只是一个最小的例子)。
我希望能够获得 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)
然后我可以使用父QWizard
的field_set
属性结合QWizard.field
to access all the values. This seems a bit redundant and therefore unnecessary. Is there a method in Qt to access the complete collection of fields? The relevant section in the documentation没有提到任何东西,但还有很多其他细节它省略了,所以这不是很有说服力。
我的假设是 PyQt4 和 PyQt5 的功能(如果存在的话)是相同的。如果不是,我更喜欢 PyQt5 的答案,因为那是我目前正在使用的。
你说如果答案是否定的,那肯定是"pretty convincing."你承认文档中没有提到你想要的功能,我要指出的是列表中没有这样的功能QWizard 的 public 个函数。因此,所需的函数(如果存在的话)是 未记录的 。对我来说,仅此考虑就是 "pretty convincing" 不使用它的理由。 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
,去掉中间两行register_field
。现在您只有五行 Python 代码,无论页面如何添加或删除,它们都可以正常工作。而且您不再将字段名称存储在两个地方。
就其价值而言,每当我面临在使用 Qt 功能还是基本 Python 功能之间做出选择时,我总是倾向于 Python。我使用线程而不是 QThreads,线程锁和定时器而不是 Qt 等价物,Python 方法对象和回调而不是自定义插槽和信号。 Qt 是为 C++ 程序员编写的,这通常意味着它并不像我想要的那样 "pythonic"。