在Qt中确定父表单的类型

时间:2017-12-10 23:21:14

标签: c++ qt pointers types parent-child

我有一个表X的数据库:让我们称之为clients。我还有一个与编辑表X内容相关的表单。它可以打开它自己(浏览/编辑)以及其他形式,当需要选择"表X中的记录。

如何告诉家长已经从QModelIndex信号处理程序直接选择了某个on_tableView_doubleClicked(const QModelIndex &index)

目前,我只有一个"爸爸" form,所以我知道哪种类型的指针以子格式放置(因此它可以保存指向父级的指针)并且只是输入了它的类型的指针。

if (parent) daddy = qobject_cast<InvoiceEd*>(parent);

现在我想从另一个表单添加一个调用,我意识到我必须从QWidget*指针中抛出不同的指针,而我不知道如何确定&#39; s&# 34;伪装&#34;在QWidget* parent指针下。我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

现有方法实现中有一个代码来解析窗口小部件类型:

// dataform.cpp
void DataForm::myEdit()
{
   ///
   if (parent()) daddy = qobject_cast<InvoiceEd*>(parent());
}

并且作者希望使其更加灵活,例如具体根据调用者强制转换为某种窗口小部件类型。那可以做到。让我们将所需的类型传递给它:

class DataForm
{
   public:
   // was void myEdit()
   template <typename T = InvoiceEd> // defaults to InvoiceEd
     void myEdit()
     {
         ///
         T* daddy = qobject_cast<T*>(parent());
         // now we operate with the proper pointer so that
         // exact instance does virtual function calls etc.
     }
///
};

pDataForm->myEdit(); // default case
pDataForm->myEdit<MutatedInvoiceEd>(); // specified case

P.S。以上是没有批评可疑的设计。在OOP中,我们通常想知道调用方法的上下文或者对象不希望彼此识别。在这种情况下,您应该为不同的用途创建两个不同的方法,或者可能提供一个额外的参数(可能使用默认值void myEdit(bool insideOfContainerEdit = true),以便代码知道一些主要用例。有很多方法可以处理,但我们不能看看你的整个代码。

但是当然,C ++中模板的存在使我们能够解决问题。我自己在模板中找到帮助,有时避免编写更多代码或从类型等派生出来,但过度使用这种方法会导致很多麻烦。理想情况下,我们应该依赖于多态的继承,或者完全通过带参数类型的模板处理这种情况。

答案 1 :(得分:2)

我建议使用界面和dynamic_cast传递有关所选项目的信息:

InvoiceEdInterface.hpp

class InvoiceEdInterface {
public:
    virtual void SetSelectedItem (SelectedItemClass i_selected_item) = 0;
};

InvoiceEd.hpp

class InvoiceEd: public InvoiceEdInterface {
public:
    void SetSelectedItem (SelectedItemClass i_selected_item) override {
        // Process setting selected item.
    }
};

DataForm.hpp

class DataForm {
...
    void on_tableView_doubleClicked(const QModelIndex &index) {
        auto invoice_ed {dynamic_cast< InvoiceEdInterface* >(parent ())};

        if (invoice_ed) {
            invoice_ed->SetSelectedItem (...);
        }
    }
...
};

解决方案背后的想法很简单:如果父窗口小部件实现指定的接口,则调用SetSelectedItem()。否则,没有任何反应。

但请注意,建议的解决方案可能不是 Qt-ish 。使用Qt,您可以添加一个通知所选项目的信号。在父窗口小部件中创建DataForm对象以选择某个项目时,父窗口小部件应建立信号槽连接。此解决方案比上面提出的解决方案更灵活,因为它允许程序中的任何对象获取有关所选项的信息。

所提出的解决方案都是动态运行的,没有基于模板的解决方案的限制。