我在完全掌握Qt中如何使用信号和插槽方面遇到了一些困难.我相信这是非常基本的,但我今天没有得到它.
我有一组小部件有点像这样:
MainWindow - > StackedWidget - > ChildForms
现在的想法是,子窗口小部件上有一些操作会导致堆叠窗口小部件显示不同的页面.
因此,如果我理解正确,我认为连接信号和插槽的方法是使用connect()
知道对象的范围,但我设法工作的方法不是这样做的.在我的子表单中,我使用parentWidget()来访问StackedWidget的插槽但我真的不是很满意,因为它给了孩子关于它不应该具有的父节点的信息:
void TaskSelectionForm::setButtonMappings()
{
// Set up a mapping between the buttons and the pages
QSignalMapper *mapper = new QSignalMapper(this);
connect(mapper, SIGNAL(mapped(int)), parentWidget(), SLOT(setCurrentIndex(int)));
mapper->setMapping(ui->utilitiesButton, 2); // Value of the index
connect(ui->utilitiesButton, SIGNAL(clicked()), mapper, SLOT(map()));
}
Run Code Online (Sandbox Code Playgroud)
但我不确定我应该怎么做并将其连接起来.我是否需要在每个级别都有信号并通过树发射?
Rei*_*ica 18
信号槽连接忽略了QObject之间的父子关系,任何这样的关系都无关紧要.您可以自由地将对象连接到他们的孩子,他们的兄弟姐妹,他们的父母,甚至连接到单独的层次结构中的QObject,或者连接既没有父母也没有孩子的QObject.没关系.
信号槽连接将QObject 的特定实例上的信号连接到另一个QObject 实例上的槽.要使用connect方法,需要指向发送方QObject实例和接收方QObject实例的指针.然后使用静态QObject::connect(sender, SIGNAL(...), receiver, SLOT(...))
.这些连接与发送方和接收方之间的任何层次结构无关.
您还可以将信号连接到信号,将其转发 - 例如从私有UI元素转换为类的API的一部分信号.您无法将插槽连接到插槽,因为它会为很少使用的情况带来一些运行时开销.开销将是bool
QObjectPrivate中的额外成员,加上失败的if (bool)
测试.如果要将插槽转发到插槽,至少有两种方法可以实现:
在源插槽中发出信号并将该信号连接到目标插槽.
获取连接到源插槽的所有信号的列表,迭代它并将它们连接到目标插槽.当进一步的信号与源插槽连接或断开时,没有简单的方法来维持这种连接.不幸的是,QObject只有一个connectNotify(const char*)
受保护的功能,但不是一个信号 - 所以你不能连接它,除非你修改src/corelib/kernel/qobject[.cpp,_p.h,.h]
发出这样的信号.如果你确实需要它,只需修改Qt源,毕竟你有理由访问它.在不修改Qt的情况下黑客攻击vtable是可能的,但由于显而易见的原因而气馁.
下面是一个自包含的示例,说明如何执行您想要的操作.事实证明,我在过去的Qt中所做的各种实验中得到了很多问题的答案.在测试代码方面,我是一个包装工具.这是所有SSCCE启动:)
// https://github.com/KubaO/stackoverflown/tree/master/questions/signal-slot-hierarchy-10783656
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif
class Window : public QWidget
{
QSignalMapper m_mapper;
QStackedLayout m_stack{this};
QWidget m_page1, m_page2;
QHBoxLayout m_layout1{&m_page1}, m_layout2{&m_page2};
QLabel m_label1{"Page 1"}, m_label2{"Page 2"};
QPushButton m_button1{"Show Page 2"}, m_button2{"Show Page 1"};
public:
Window(QWidget * parent = {}) : QWidget(parent) {
// the mapper tells the stack which page to switch to
connect(&m_mapper, SIGNAL(mapped(int)), &m_stack, SLOT(setCurrentIndex(int)));
// Page 1
m_layout1.addWidget(&m_label1);
m_layout1.addWidget(&m_button1);
// tell the mapper to map signals coming from this button to integer 1 (index of page 2)
m_mapper.setMapping(&m_button1, 1);
// when the button is clicked, the mapper will do its mapping and emit the mapped() signal
connect(&m_button1, SIGNAL(clicked()), &m_mapper, SLOT(map()));
m_stack.addWidget(&m_page1);
// Page 2
m_layout2.addWidget(&m_label2);
m_layout2.addWidget(&m_button2);
// tell the mapper to map signals coming from this button to integer 0 (index of page 1)
m_mapper.setMapping(&m_button2, 0);
connect(&m_button2, SIGNAL(clicked()), &m_mapper, SLOT(map()));
m_stack.addWidget(&m_page2);
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8350 次 |
最近记录: |