C++ 在另一个类中更改小部件类型的行为

C++ 在另一个类中更改小部件类型的行为,c++,qt,C++,Qt,我在Qt中有一个MainWindow类,其中放置了几个可检查的QGroupBox小部件 我想做的是,每当点击QGroupBox对象中的一个(any)时,就触发一个通用onClick(bool checked)插槽,识别发送方并触发一些代码 我需要捕获对象的“单击”信号,以防止在单击控件时对其子对象执行禁用操作 这是我试图处理的信号: class Q_WIDGETS_EXPORT QGroupBox : public QWidget { ... Q_SIGNALS:

我在Qt中有一个MainWindow类,其中放置了几个可检查的QGroupBox小部件

我想做的是,每当点击QGroupBox对象中的一个(any)时,就触发一个通用onClick(bool checked)插槽,识别发送方并触发一些代码

我需要捕获对象的“单击”信号,以防止在单击控件时对其子对象执行禁用操作

这是我试图处理的信号:

class Q_WIDGETS_EXPORT QGroupBox : public QWidget
{
    ...
    Q_SIGNALS:
        void clicked(bool checked = false);
    ...
};
我尝试添加这样一个自定义插槽,并尝试将其与上面的信号连接,但由于QGroupBox本身不是对象或指针,因此操作失败

void MainWindow::onClick(bool clicked)
{
    qDebug()<<"Custom slot triggered";
}
void主窗口::onClick(bool单击)
{
qDebug()
我需要捕获对象的“单击”信号,以防止在单击控件时对其子对象执行禁用操作

也许吧,但我在这里闻到了一种气味。你当然可以通过调用小部件上的
blockSignals()
来防止信号的发射。但这是一种黑客行为——它还可以防止Qt的内部对对象的
destromed()
信号起作用,并且你可能会巧妙地破坏对象信号的其他用户

相反,可以使UI有状态,并让控制器实现按钮与应用程序其余部分交互的有状态方面
信号直接连接到其他用户。相反,将按钮连接到控制器,并让控制器仅在适当的时候禁用子项。可以使用
QStateMachine
使此有状态行为在状态方面显式

我需要捕获对象的“单击”信号,以防止在单击控件时对其子对象执行禁用操作

也许吧,但我在这里闻到了一种气味。你当然可以通过调用小部件上的
blockSignals()
来防止信号的发射。但这是一种黑客行为——它还可以防止Qt的内部对对象的
destromed()
信号起作用,并且你可能会巧妙地破坏对象信号的其他用户


相反,可以使UI有状态,并让控制器实现按钮与应用程序其余部分交互的有状态方面信号直接连接到其他用户。相反,请将按钮连接到控制器,并让控制器仅在适当的时候禁用子项。可以使用
QStateMachine
使这种有状态的行为在状态方面显式化。

@Kuba Ober,也许你是对的,我无法说明我的专业问题和它周围的事实分开和清楚。谢谢你指出这一点

在检查QGroupBox类的源代码后,我发现在“单击”事件中,每隔一次操作都会发出一个“切换”信号

通过将这些信息与@rbaleksandar的建议结合起来,我成功地获得了一个解决方案

我迭代了MainWindow类的控件,并将每个QGroupBox的“toggle”信号与一个公共的“MainWindow::onToggle”插槽连接起来,在这个插槽中我可以处理所需的事件后操作

至于我以前的方法,我本可以创建一个继承QGroupBox并覆盖任何我希望覆盖的方法的类。但与我当前的解决方案相比,这将是过度的。我提出的修复方案完美地实现了这一点


谢谢大家的洞察力和帮助。

@Kuba Ober,也许你是对的,我无法将我的问题和周围的事实分开清楚地陈述出来。谢谢你指出这一点

在检查QGroupBox类的源代码后,我发现在“单击”事件中,每隔一次操作都会发出一个“切换”信号

通过将这些信息与@rbaleksandar的建议结合起来,我成功地获得了一个解决方案

我迭代了MainWindow类的控件,并将每个QGroupBox的“toggle”信号与一个公共的“MainWindow::onToggle”插槽连接起来,在这个插槽中我可以处理所需的事件后操作

至于我以前的方法,我本可以创建一个继承QGroupBox并覆盖任何我希望覆盖的方法的类。但与我当前的解决方案相比,这将是过度的。我提出的修复方案完美地实现了这一点


感谢大家的见解和帮助。

您是如何做到的“我在MainWindow.cpp文件中成功重写了QGroupBox类的setChecked方法”?我真的不知道,但我只是在我的MainWindow类中写了方法名,当加载MainWindow时,我添加到MainWindow的每个QGroupBox都会触发一次该方法。你不能通过不继承该类来覆盖类的方法。然后我猜这是一个随机的情况,在这种情况下,该方法以某种方式注册到所有者类的信号。这可能是我在代码中的其他地方做的。但是如果我在主窗口中放置了3个组框,我肯定会看到3个触发器。尽管如此,这种现象与我的实际问题不太相关,因此我将删除它以防分心。你可以得到给定类型的所有子对象(例如,通过
findChildren(…)
)然后自动连接这些(这也应该有助于您做到这一点)。您是如何做到的“我设法在我的MainWindow.cpp文件中覆盖了QGroupBox类的setChecked方法”?我真的不知道,但我只是在我的MainWindow类中写了方法名,当加载MainWindow时,我添加到MainWindow的每个QGroupBox都会触发一次该方法。你不能通过不继承该类来覆盖类的方法。然后我猜这是一个随机的情况,在这种情况下,该方法以某种方式注册到所有者类的信号。这可能是我在代码中的其他地方做的。但是如果
void QGroupBox::setChecked(bool b)
{
    Q_D(QGroupBox);
    if (d->checkable && b != d->checked) {
        update();
        d->checked = b;
        d->_q_setChildrenEnabled(b);
#ifndef QT_NO_ACCESSIBILITY
        QAccessible::State st;
        st.checked = true;
        QAccessibleStateChangeEvent e(this, st);
        QAccessible::updateAccessibility(&e);
#endif
        emit toggled(b);
    }
}