【问题标题】:Why can I not force a PyQt tabbed widget to resize? [duplicate]为什么我不能强制 PyQt 选项卡式小部件调整大小? [复制]
【发布时间】:2020-05-24 21:49:10
【问题描述】:

我有一个包含 QTabWidget 的 QDialog,它的选项卡大小不同。在these instructions 之后,类似于另一个stack overflow answer,我有以下代码(self.tabs 是标签小部件的字典):

class Panel(NXDialog):

    def __init__(self, panel, parent=None):
        super(Panel, self).__init__(parent)
        self.tabwidget = QtWidgets.QTabWidget()
        self.tabwidget.currentChanged.connect(self.update)
        ...

    @property
    def tab(self):
        return self.tabwidget.currentWidget()

    def update(self):
        if self.tabwidget.count() == 0:
            self.setVisible(False)
        else:
            for tab in [tab for tab in self.tabs if tab is not self.tab]:
                try:
                    self.tabs[tab].setSizePolicy(QtWidgets.QSizePolicy.Ignored, 
                                                 QtWidgets.QSizePolicy.Ignored)
                    self.tabs[tab].update()
                except Exception:
                    pass
            self.tab.setSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                   QtWidgets.QSizePolicy.Preferred)
            self.tab.update()
        self.adjustSize()

当我添加一个新标签时,效果很好。该选项卡确实可以根据需要调整大小。但是,即使我的调试器确认调用了此更新函数,选项卡选择中的后续更改也没有效果。

我的应用程序有一个嵌入式 shell,它与 GUI 共享一个命名空间,因此我可以处理所有 PyQt 小部件。如果我在 shell 中调用tab.adjustSize(),其中选项卡指向所选选项卡,则选项卡会调整大小!所以我的问题是为什么adjustSize 函数在我使用GUI 进行选择并触发currentChanged 信号时被忽略,但当我稍后从shell 调用相同的槽函数时不会被忽略。我已经尝试添加一个睡眠时间并递归地循环通过调用adjustSize 的父小部件,但它没有效果。我还尝试添加self.repaint() 以及以编程方式更改焦点并再次返回,但除了从shell 中键入它之外没有任何作用。

我在 Python 3.8 上运行 PyQt5 v5.12.5,但我在 PyQt v5.9 上得到了相同的行为。

【问题讨论】:

  • 我真的不认为这在这里会有帮助,因为我的应用程序非常大,有许多相互连接的部分。这不是错误报告。我希望社区中的某个人可以根据他们在类似问题上的经验提出尝试的建议。
  • 这里我们需要一个 MRE,如果你的应用程序非常大,那么它就不是 MRE,所以你必须努力创建一个只关注功能的新项目,然后这将是MRE。这些是 SO 规则。请阅读How to Ask 并查看tour
  • 我已经阅读了数千个未提供 MRE 的 SO 问题,但收到了多个有用的 cmets。事实上,我刚刚遇到了另一个我认为可以解决问题的 SO 页面,但也没有 MRE。我会尽快发布。
  • 如果答案已经存在,那么不要发布相同的答案,还要记住 SO 规则已经改变。

标签: python pyqt pyqt5


【解决方案1】:

另一个stackoverflow question 帮助我解决了这个问题。 SizePolicy 中的先前更改似乎仍在 GUI 事件循环中等待。首先清除循环可确保adjustSize 正常工作。

这就是我们所需要的。

        QtWidgets.QApplication.instance().processEvents()        
        self.adjustSize()

我承认我很惊讶我以前没有遇到过这个问题,但我希望它对遇到同样问题的其他人有所帮助。

【讨论】:

  • 虽然我认为这个答案基本上仍然是正确的,但它触发了另一个 PyQt5 错误,如果该小部件仍然打开,它会导致应用程序在退出时崩溃。我相信这与@ekhumoro here 的答案中描述的错误相同。我认为它会影响 PyQt5 v5.12 和 v5.13,但不会影响 v5.9。
  • 如果将来允许任何人阅读此内容,上述评论中的问题已根据 PyQt 邮件列表 (riverbankcomputing.com/pipermail/pyqt/2020-May/042923.html) 上的建议得到修复。诀窍是在调用 QApplication 退出方法之前显式关闭所有顶级小部件。删除 QApplication 实例本身似乎没有必要。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-05
  • 2023-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多