连接(以一种不寻常的方式)信号到插槽

Connecting (in an unusual way) signals to slots

本文关键字:信号 方式 插槽 一种 连接 不寻常      更新时间:2023-10-16

我设计了这样的结构:

template<class Ui_Class>
class Base_Dialog : virtual public QDialog, protected Ui_Class
{
protected:
    QDialog* caller_;
public:
    template<class Implementation>
    Base_Dialog(Implementation*const & imp,QDialog *caller,QWidget* parent = nullptr);
};
template<class Ui_Class>
template<class Implementation>
Base_Dialog<Ui_Class>::Base_Dialog(Implementation*const& imp,QDialog *caller,QWidget* parent):
    QDialog(parent),
    caller_(caller)
{
    setupUi(imp);
}

我是这样用的:

class My_Class : public **Base_Dialog<Ui::My_Class>**
{
    Q_OBJECT

public slots:
    void display_me()
    {/*THIS IS NOT GETTING CONNECTED*/
        QMessageBox::warning(this,"Aha!","Aha!");
    }
public:
    explicit My_Class(QDialog* caller = nullptr,QWidget *parent = nullptr);
};
Line_Counter::Line_Counter(QDialog* caller,QWidget *parent) :
    Base_Dialog(this,caller,parent)
{
    //setupUi(this);//THIS WORKS BUT I'D RATHER CALL IT FROM Base_Dialog

}

上面的构造是为了简化从QDialog和Ui类继承的方式。这是有效的,除了当槽和信号在我的类中引入时,基类由于某种原因看不到它们(槽/信号)。如果我在My_Class中调用setupUi,一切都正常工作,但我更喜欢在Base_Class中调用它。有办法吗?

lineCounter的构造函数也应该重命名为My_Class,对吗?

这种行为的原因是,从virtual const QMetaObject * metaObject() const的Base_Dialog的构造函数中返回的元对象是Base_Dialog的元对象,因为在这个阶段它还不是My_Class实例的实例。My_CLass覆盖这个虚方法(在Q_OBJECT宏中不可见),但只在My_CLass构造函数代码开始执行之后——也就是说在Base_Dialog代码完成之后。信号和槽在连接时内部使用元对象,所以这种方式似乎不起作用。

总结-你不能这样做,因为Base_Dialog的构造函数不知道My_Class实例正在被创建,因此不能访问它的任何内容。

有时这个问题可以使用CRTP绕过,但在这种情况下,我不知道它是否适用。我宁愿选择做Qt的方式-从My_Class构造函数调用setupUi。