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

时间:2011-12-25 19:05:29

标签: c++ qt

我设计了一些像这样的结构:

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 ctor一切正常,但我更喜欢在Base_Class中调用它。有办法吗?

1 个答案:

答案 0 :(得分:1)

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。