gpt4 book ai didi

qt - 通过层次结构传递信号

转载 作者:行者123 更新时间:2023-12-03 22:10:38 25 4
gpt4 key购买 nike

我在完全掌握 Qt 中如何使用信号和插槽时遇到了一些困难。我确信它真的很基本,但我今天就是不明白。

我有一组有点像这样的小部件:

主窗口
-->StackedWidget
-->子窗体

现在的想法是子小部件上的一些操作将导致堆叠的小部件显示不同的页面。

因此,如果我理解正确,我认为连接信号和插槽的方法是使用 connect()在了解对象但我设法开始工作的范围内并没有这样做。目前在我的子表单中,我使用 parentWidget() 来访问 StackedWidget 的插槽,但我真的不是很满意,因为它给了 child 关于它不应该拥有的 parent 的信息:

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()));
}

但我不确定我应该如何做到这一点并将其连接起来。我是否需要在每个级别都有信号并通过树发出?

最佳答案

一点信号槽理论

信号槽连接忽略了 QObject 之间的父子关系,任何这样的关系都无关紧要。您可以自由地将对象连接到他们的 child 、他们的 sibling 、他们的 parent ,甚至是在一个单独的层次结构中的 QObjects,或者连接到既没有 parent 也没有 child 的单独的 QObjects。没关系。

信号槽连接将 QObject 的特定实例上的信号连接到 QObject 的另一个实例上的槽。要使用 connect 方法,您需要指向发送方 QObject 实例和接收方 QObject 实例的指针。然后使用静态 QObject::connect(sender, SIGNAL(...), receiver, SLOT(...)) .这些连接与发送者和接收者之间的任何层次结构无关。

您还可以将信号连接到信号以进行转发——例如从私有(private) UI 元素到作为类 API 一部分的信号。您不能将插槽连接到插槽,因为对于很少使用的情况,它会产生一些运行时开销。开销将是额外的 bool QObjectPrivate 中的成员,加上失败的 if (bool)测试。如果要将插槽转发到插槽,至少有两种方法:

  • 在源槽中发出信号并将该信号连接到目标槽。
  • 获取连接到源槽的所有信号的列表,对其进行迭代并将它们连接到目标槽。当进一步的信号从源插槽连接或断开时,没有简单的方法来维持这种连接。不幸的是,QObject 只有一个 connectNotify(const char*) protected 函数,但不是信号——所以除非你修改 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();
    }

    关于qt - 通过层次结构传递信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10783656/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com