我设计了一些像这样的结构:
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中调用它。有办法吗?
答案 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。