如何使用 Qt 将一个 Widget 替换为另一个 Widget?

发布于 2024-10-10 19:47:33 字数 1814 浏览 3 评论 0原文

我有一个 QHBoxLayout,左侧有一个 QTreeWidget,中间有一个分隔符,右侧有一个小部件。

当我单击 QTreeWidget 时,我想更改右侧的小部件以修改 QTreeWidgetItem

我尝试使用以下代码执行此操作:

def new_rendez_vous(self):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = RendezVousManagerDialog(self.parent)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

def edit(self, category, rendez_vous):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = RendezVousManagerDialog(self.parent, category, rendez_vous)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

def edit_category(self, category):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = CategoryManagerDialog(self.parent, category)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

但它不起作用并且所有小部件都彼此堆叠在一起:

错误示例
(来源:free.fr )

你知道我如何删除旧的小部件并接下来显示新的小部件吗?

I have an QHBoxLayout with a QTreeWidget on the left, a separator on the middle and a widget on the right.

When I click on the QTreeWidget, I want to change the widget on the right to modify the QTreeWidgetItem

I tried to do this with this code :

def new_rendez_vous(self):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = RendezVousManagerDialog(self.parent)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

def edit(self, category, rendez_vous):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = RendezVousManagerDialog(self.parent, category, rendez_vous)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

def edit_category(self, category):
    self.ui.horizontalLayout_4.removeWidget(self.ui.editionFormWidget)
    del self.ui.editionFormWidget
    self.ui.editionFormWidget = CategoryManagerDialog(self.parent, category)
    self.ui.editionFormWidget.show()
    self.ui.horizontalLayout_4.addWidget(self.ui.editionFormWidget)
    self.connect(self.ui.editionFormWidget, QtCore.SIGNAL('saved'), self.scheduleTreeWidget.updateData)

But it doesn't work and all the widgets are stacked up on each other :

Exemple of the bug
(source: free.fr)
.

Do you know how I can remove the old widget and next display the new one ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很OK 2024-10-17 19:47:33

我和纳蒂姆有同样的问题。

QStackedWidget 是预设布局的解决方案。它的作用就像旧餐馆里的音乐盒一样轻薄。 (点唱机中的专辑数量为 X,翻阅已安装的专辑)。

然而这并不能解决问题。

例如,我有一个使用 UI 布局进行原型设计的代码,但是我想用在主脚本执行期间编码或动态创建的正确小部件替换一些充当占位符的小部件。

我确信有一个简单的程序或警告可以说明如何正确删除/更换小部件。

我的代码在网格布局中有一个基本的文本编辑小部件。我想编写一个用于拖放的小部件的自定义版本,然后将其与默认的文本编辑交换。

和 Natim 一样,代码看起来在逻辑上是合理的,但小部件却像扔钱包一样随意地堆放在布局中。

希望能找出其中的窍门并重新发布警告。

解决方案:

瞧!找到了绝对有效的东西。关闭您的小部件

#  Remove, Create, Replace
    self.ui.gridLayout.removeWidget(self.ui.dragDataEdit)
    self.ui.dragDataEdit.close()
    self.ui.dragDataEdit = myDumpBox(self.ui.centralwidget)
    self.ui.gridLayout.addWidget(self.ui.dragDataEdit, 0, 0, 1, 1)
    self.ui.gridLayout.update()

我从布局中删除了该小部件,然后关闭了该小部件。此时,我使用的变量已打开以创建我的自定义/修改后的小部件,然后将其重新插入到布局中

是的,需要一些更优雅的处理更复杂的布局,但基本需要按顺序销毁小部件替换它是在 .close() 方法中

干杯..希望这会有所帮助。

I have the same question as Natim.

The QStackedWidget is a solution for a preset layout. It acts like the flippy thing in an old diner for a music box. (X-amount of albums in the jukebox, flip through the installed albums).

However this does not solve the question.

For instance I have code I am prototyping with a UI layout, however I want to replace some of the widgets that are acting as place-holders with the proper widgets that are coded during the primary script execution, or is dynamically created.

I am sure there is a simple procedure or caveat as to how to properly remove/replace a widget.

The code I have has a basic textEdit widget in a grid layout. I want to code a custom version of this widget for drag and drops and then swap it out with the default textEdit.

Like Natim, the code seems logically sound, however the widgets are hap-hazardly piled in the layout like dumping a purse.

Hopefully can figure out the trick to this and repost the caveat.

SOLUTION:

Voilà!! Found something that definitely does the trick. CLOSE your widget

#  Remove, Create, Replace
    self.ui.gridLayout.removeWidget(self.ui.dragDataEdit)
    self.ui.dragDataEdit.close()
    self.ui.dragDataEdit = myDumpBox(self.ui.centralwidget)
    self.ui.gridLayout.addWidget(self.ui.dragDataEdit, 0, 0, 1, 1)
    self.ui.gridLayout.update()

I removed the widget from the layout, then closed the widget. At this time the variable I am using is open to create my custom/modified widget, and then re-insert it into the layout

Yes some more elegance is needed to deal with more complicated layouts, but the basic need of destroying a widget in order to replace it is in the .close() method

Cheers.. hope this helps.
B

蔚蓝源自深海 2024-10-17 19:47:33

最常见的解决方案是使用 QStackedWidget 并放置将所有可能的小部件放入堆栈中。选择一项时,只需调用setCurrentWidget即可显示您想要的项。

The most common solution is to use QStackedWidget and put all possible widgets into the stack. When selecting an item, just call setCurrentWidget to display the one you want.

小鸟爱天空丶 2024-10-17 19:47:33

实际上,至少对于 Qt5 来说,有一个更紧凑的替代方案可以替代 B4adle7 的解决方案,利用 QLayout 的 replaceWidget

containing_layout = placeholder.parent().layout()
containing_layout.replaceWidget(placeholder, new_widget)

额外提示:

您希望在运行时将自定义小部件放入其中,并且您正在使用ui-files ?请改用推广自定义小部件! 这里是一篇很好的帖子,其中包含有关如何在 PyQt 的 Qt 设计器

PySide中,其工作原理类似。您无需将自定义小部件的源文件指定为头文件,而是在用于通过 registerCustomWidget()

Actually, as for Qt5 at least, there is a more compact alternative to B4adle7's solution utilizing QLayout's replaceWidget:

containing_layout = placeholder.parent().layout()
containing_layout.replaceWidget(placeholder, new_widget)

Extra hint:

You want to put a custom widget into place with this at runtime and you are using ui-files? Use promoting to custom widgets instead! Here is a good post with screenshots about how to configure a custom widget inside Qt designer for PyQt.

In PySide this works similar. Instead of specifying the source file of the custom widget as header file, you would register your custom widget class in the QUiLoader instance used to load the ui-file via registerCustomWidget() in Python code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文