【问题标题】:Repetitive PyQT references重复的 PyQT 引用
【发布时间】:2021-12-06 17:41:21
【问题描述】:

我有一个在 QT Designer 中设计的 PyQT UI,有 40 个图形(在不同的选项卡上),以及对 UI 中元素的大量重复引用。例如,以下唯一的文本字段,用于设置每个图形的标题。

    # Tab 1
    self.tab1_tl1.canvas.axes.set_title(self.tab1_tl1_title.text())
    self.tab1_tl2.canvas.axes.set_title(self.tab1_tl2_title.text())
    self.tab1_tl3.canvas.axes.set_title(self.tab1_tl3_title.text())
    self.tab1_tl4.canvas.axes.set_title(self.tab1_tl4_title.text())
    self.tab1_tl1.canvas.axes.set_ylabel(self.tab1_tl1_ylabel.text())
    self.tab1_tl2.canvas.axes.set_ylabel(self.tab1_tl2_ylabel.text())
    self.tab1_tl3.canvas.axes.set_ylabel(self.tab1_tl3_ylabel.text())
    self.tab1_tl4.canvas.axes.set_ylabel(self.tab1_tl4_ylabel.text())
    # Tab 2
    self.tab2_tl1.canvas.axes.set_title(self.tab2_tl1_title.text())
    self.tab2_tl2.canvas.axes.set_title(self.tab2_tl2_title.text())
    self.tab2_tl3.canvas.axes.set_title(self.tab2_tl3_title.text())
    self.tab2_tl4.canvas.axes.set_title(self.tab2_tl4_title.text())
    self.tab2_tl1.canvas.axes.set_ylabel(self.tab2_tl1_ylabel.text())
    self.tab2_tl2.canvas.axes.set_ylabel(self.tab2_tl2_ylabel.text())
    self.tab2_tl3.canvas.axes.set_ylabel(self.tab2_tl3_ylabel.text())
    self.tab2_tl4.canvas.axes.set_ylabel(self.tab2_tl4_ylabel.text())

您可以想象,代码变得非常冗长。有没有更有效的方法来遍历所有这些引用和字段?

【问题讨论】:

  • 您可以使用 getattrsetattr 例如或将您的元素存储在list 等中。但一个好的解决方案也很大程度上取决于环境和您的个人偏好。
  • 你应该分解更多。带有多个选项卡和图形的单个 ui 文件似乎不是一个好的设计解决方案。它应该是单独的小部件,尽可能小。
  • tab1_tl1 对象是 Qt Designer 中提升的小部件吗?如果是这样,您可以使用带有正则表达式的QObject.findChildren 将它们全部提取到基于它们的objectName 的列表中。然后您可以对其进行迭代并使用objectName 来获取其他小部件,如下所示:title = getattr(self, f'{widget.objectName()}_title').text()。这可能会将整个代码减少到 3-4 行代码。

标签: python user-interface pyqt


【解决方案1】:

你应该把对应的 tl、title 和 ylabel 放在一个字典里,并把它们排列在一个嵌套列表中,而不是把名字写成tab1_tl1

像这样创建它们:

tabs = [] 
for i in range(tabCount):
    tab = []
    tabs.append(tab)

    for j in range(tlCount):
        tab.append(dict(
          obj = create_tl(i,j)),
          title = create_title(i,j),
          ylabel = create_ylabel(i,j)  )
      

现在tabs[i][j] 对应于tabi_tlj,它是一个包含实际 tl 对象、标题和 ylabel 的字典。 所以你可以像这样更新属性:

for tab in tabs:        
    for tl in tab:
        tl['obj'].canvas.axes.set_title(tl['title'])
        tl['obj'].canvas.axes.set_ylabel(tl['ylabel'])

一般来说创建编号变量是不好的。清单就是为此而存在的。也总是在字典或对象中收集相关的重复对象。

【讨论】:

  • 这种方法在这种情况下实际上不起作用,因为属性都是从 Qt Designer 创建的 ui 文件自动生成的。
【解决方案2】:

正如我在 cmets 中所说,您可以使用 getattr,但没有进一步的上下文,这是我能建议的最好的:

for i in range(1, 41):
    for j in range(1, 5):
        ax = getattr(self, f'tab{i}_tl{j}').canvas.axes
        title = getattr(self, f'tab{i}_tl{j}_title').text()
        ylabel = getattr(self, f'tab{i}_tl{j}_ylabel').text()
        ax.set_title(title)
        ax.set_ylabel(ylabel)

【讨论】:

  • 感谢 mapf,这非常有效!我将它应用到代码的其他区域,并将程序从大约 2300 行减少到 1400 行。
  • 现在减少到 730 行。谢谢!!!
猜你喜欢
  • 2019-05-25
  • 2011-07-06
  • 2020-02-27
  • 2010-11-10
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多