我可以将“this”传递给 Q_Slot 吗?
Posted
技术标签:
【中文标题】我可以将“this”传递给 Q_Slot 吗?【英文标题】:Can I pass "this" to a Q_Slot? 【发布时间】:2017-02-16 14:10:28 【问题描述】:我有一个带有许多窗口(QWidgets)的应用程序。 不过,我没有保存打开的窗口列表,所以每次我想关闭一个窗口时,我都必须检索它。
特别是,这些窗口中的每一个在此处被称为 SubWindow。 每个 SubWindow 类都包含一个带有 MultiEditor *sEditors 的布局,它有一个带有关闭当前窗口的操作的菜单。 每个子窗口都是在主窗口中创建的。
我有两个计划。 1) 通过添加 SubWindow 构造函数,从自身内部销毁 SubWindow
connect(sEditors, SIGNAL(closeWindow()),
this, closeWindow()));
或
2) 通过添加 SubWindow 构造函数,从 MainWindow 类中销毁 SubWindow
connect(sEditors, SIGNAL(closeWindow()),
main, SLOT(closeWindow(this)));
关于 1),我不明白如何从内部关闭和销毁 QWidget(删除它; 似乎不起作用,但我可以再试一次)。
关于 2) 我的 SLOT(closeWindow(this)) 似乎没有被触发,所以我想知道是否可以将“this”作为参数传递。
【问题讨论】:
【参考方案1】:广告 1) 您可以使用QObject::deleteLater()
。这将在下一个事件循环周期中销毁对象,并且专门为此类情况创建
Ad 2) 您不能在信号槽连接中将实际参数作为参数传递。
但是,您可以使用插槽中的sender()
函数找出谁发出了信号。在您的情况下,这将是 sEditors
对象。
其他选项:
3) 您可以使用QSignalMapper
将信号从您的编辑器映射到子窗口。
4)(使用 Qt5 / C++11)您可以在子窗口中使用 lambda 连接:
connect(sEditors, SIGNAL(closeWindow()), [this] () this->closeWindow(););
【讨论】:
出于某种原因(我不知道),我的 deleteLater() 无法正常工作。我在 closeWindow() 中触发它并且我的 QWidget 仍然存在 - >它不会消失。即使我写 close() [或 this->close()] 或 hide() [this->hide()],QWidget 也不会消失 您似乎正在关闭/删除/隐藏错误的小部件。使用调试器验证this
是否指向插槽中的正确对象【参考方案2】:
我可以将
this
传递给 Qt 插槽吗?
槽是一个非静态方法,所以它已经可以访问this
。您所指的this
是QObject::connect
的第三个参数。在 Qt 4 语法中,您可以省略第三个参数 - 它默认为 this
。不过,在 Qt 5 语法中,您必须明确说明。
我不明白如何从内部关闭和销毁 QWidget
要从其内部删除任何QObject
,请使用QObject::deleteLater()
。回想一下,QWidget
在LSP 中是一个QObject
。
我的 SLOT(closeWindow(this)) 似乎没有被触发
没有这样的插槽(给我们一个指向它的文档的链接:你不能),并且你的插槽签名也是无效的,因为插槽签名中括号内的唯一内容可以是类型,而 this
不是一个类型:SLOT(slotName(TYPE_LIST_HERE))
,例如SLOT(mySlot(int,QString))
.
要关闭小部件,请使用其close()
插槽:
connect(sEditors, SIGNAL(closeWindow()), this, SLOT(close());
然而,通过使用 Qt 4 connect
语法,您将在运行时检测到编码错误 - 如果您在运行时不注意调试输出,您就会错过它。因此最好使用新的 (Qt 5) connect
语法,并让编译器为您检测错误:
connect(sEditors, &MultiEditor::closeWindow, this, &QWidget::close);
唉,没有必要将发送closeWindow
的对象紧密耦合到SubWindow
- 至少不在SubWindow::SubWindow()
内。相反,您可以在创建编辑器的地方进行连接。
要在小部件关闭时删除它,只需在其上设置Qt::WA_DeleteOnClose
属性并让Qt 为您完成。无需显式调用deleteLater
等。
你可以把它全部分解成一个工厂方法:
template <class T> T* SubWindow::makeEditor()
auto sub = new Tthis;
sub->setAttribute(Qt::WA_DeleteOnClose);
connect(sEditor, &MultiEditor::closeWindow, sub, &QWidget::close);
return sub;
MainWindow::MainWindow(/*...*/) : /*...*/
makeEditor<EditorType1>();
makeEditor<EditorType2>();
/*...*/
【讨论】:
Qt5 语法非常有用,谢谢!由于某种原因(我不知道),我的 deleteLater() 不起作用。我在 closeWindow() 函数中触发它,我的 QWidget 仍然存在 - >它不会消失。即使我写 close() [或 this->close()] 或 hide() [this->hide()],QWidget 也不会消失,即使我写 connect(sEditors, &MultiEditor::closeWindow, this, &QWidget::close);以上是关于我可以将“this”传递给 Q_Slot 吗?的主要内容,如果未能解决你的问题,请参考以下文章
我可以将 String[] 列表传递给 Freemarker 吗?