确定QT中父型的类型

Determining type of parent form in Qt

本文关键字:类型 父型 QT 确定      更新时间:2023-10-16

我有一个带有表X的数据库:我们称其为 clients。我也有与编辑表x内容有关的表格。它可能会自行打开(浏览/编辑)以及从表X中"选择"记录时从其他形式打开。

我该如何告诉父母,特定的QModelIndex已直接从on_tableView_doubleClicked(const QModelIndex &index)信号处理程序中挑选出来?

目前,我只有一种"爸爸"表格,所以我知道要将哪种指针放入子形式(因此它可以容纳父母的指针),然后铸造了它的类型指针。

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

现在,我想添加来自另一种形式的呼叫,我意识到我必须将其他指针从QWidget*指针中投射出来,并且我不知道如何确定QWidget* parent指针下的"变相"。我该怎么做?

我建议使用接口和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对象以选择某些项目时,父窗口小部件应建立信号插槽连接。该解决方案比上述解决方案更灵活,因为它允许程序中的任何对象获取有关所选项目的信息。

两种建议的解决方案动态工作,而没有基于模板的解决方案的局限性。

在某些现有方法实现中有一个代码来解决小部件类型:

// 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 中模板的存在使我们能够将问题解决到程度上。我本人在模板中找到帮助,有时避免编写更多代码或从类型等中得出,但是过度使用这种方法会导致很多头痛。理想情况下,我们应该依靠多态性的继承或完全通过具有参数类型的模板处理此类情况。