Qt 我能通过吗;这";到Q_槽?

Qt 我能通过吗;这";到Q_槽?,qt,signals-slots,qwidget,Qt,Signals Slots,Qwidget,我有一个带有许多窗口(QWidgets)的应用程序。 不过,我没有保存打开窗口的列表,所以每次我想关闭窗口时,都必须检索它 特别是,这些窗口中的每一个都称为此处子窗口。 每个子窗口类都包含一个带有MultiEditor*sEditors的布局,该布局具有一个带有关闭当前窗口的操作的菜单。 每个子窗口都是在主窗口中创建的 我有两个计划。 1) 通过添加子窗口构造函数,从子窗口内部销毁子窗口 connect(sEditors, SIGNAL(closeWindow()), this,

我有一个带有许多窗口(QWidgets)的应用程序。 不过,我没有保存打开窗口的列表,所以每次我想关闭窗口时,都必须检索它

特别是,这些窗口中的每一个都称为此处子窗口。 每个子窗口类都包含一个带有MultiEditor*sEditors的布局,该布局具有一个带有关闭当前窗口的操作的菜单。 每个子窗口都是在主窗口中创建的

我有两个计划。 1) 通过添加子窗口构造函数,从子窗口内部销毁子窗口

connect(sEditors, SIGNAL(closeWindow()),
        this, closeWindow()));
connect(sEditors, SIGNAL(closeWindow()),
        main, SLOT(closeWindow(this)));

2) 通过添加子窗口构造函数,从MainWindow类中销毁子窗口

connect(sEditors, SIGNAL(closeWindow()),
        this, closeWindow()));
connect(sEditors, SIGNAL(closeWindow()),
        main, SLOT(closeWindow(this)));
关于1),我不明白如何从内部关闭和销毁QWidget(删除这个;似乎不起作用,但我可以再试一次)

大约2)我的插槽(closeWindow(this))似乎没有被触发,因此我想知道是否可以将“this”作为参数传递。

Ad 1)您可以使用
QObject::deleteLater()
。这将在下一个事件循环周期中销毁对象,并且是专门为此类情况创建的

Ad 2)不能在信号插槽连接中将实际参数作为参数传递。 但是,您可以使用插槽中的
sender()
函数找出是谁发出了信号。在您的例子中,这将是
sEditors
对象

其他选择:

3) 您可以使用
QSignalMapper
将来自编辑器的信号映射到子窗口

4) (使用Qt5/C++11)您可以在子窗口中使用lambda连接:

connect(sEditors, SIGNAL(closeWindow()), [this] () {this->closeWindow();});
我可以将此
传递到Qt插槽吗

插槽是一种非静态方法,因此它已经可以访问此
。您引用的
QObject::connect
的第三个参数。在Qt4语法中,可以省略第三个参数-它默认为
this
。不过,在Qt5语法中,您必须明确说明这一点

我不明白如何从内部关闭和销毁QWidget

要从自身中删除任何
QObject
,请使用
QObject::deleteLater()
。回想一下,一个
QWidget
是一个
QObject

我的插槽(closeWindow(此))似乎未被触发

没有这样的槽(给我们一个链接到它的文档:你不能),你的槽签名也是无效的,因为槽签名中括号内的东西只能是类型,
this
不是类型:
slot(slotName(type\u LIST\u这里))
,例如
slot(mySlot(int,QString))

要关闭小部件,请使用其
close()
插槽:

connect(sEditors, SIGNAL(closeWindow()), this, SLOT(close());
然而,通过使用qt4
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 T{this};
  sub->setAttribute(Qt::WA_DeleteOnClose);
  connect(sEditor, &MultiEditor::closeWindow, sub, &QWidget::close);
  return sub;
}

MainWindow::MainWindow(/*...*/) : /*...*/ {
  makeEditor<EditorType1>();
  makeEditor<EditorType2>();
  /*...*/
}
模板T*子窗口::makeEditor(){
auto sub=新的T{this};
sub->setAttribute(Qt::WA_DeleteOnClose);
连接(sEditor和MultiEditor::closeWindow、sub和QWidget::close);
返回子节点;
}
主窗口::主窗口(/*…*/):/*…*/{
makeEditor();
makeEditor();
/*...*/
}

由于某种原因(我不知道),我的deleteLater()无法工作。我在closeWindow()中触发它,我的QWidget保持->它不会消失。即使我写close()[或this->close()]或hide()[this->hide()],QWidget也不会消失。似乎您关闭/删除/隐藏了错误的小部件。验证
是否使用调试程序指向插槽中的正确对象Qt5语法非常有用,谢谢!由于某种原因(我不知道),我的deleteLater()无法工作。我在closeWindow()函数中触发它,我的QWidget保持->它不会消失。即使我写close()[或this->close()]或hide()[this->hide()],或者我写connect(sEditors,&MultiEditor::closeWindow,this,&QWidget::close),QWidget也不会消失;