如何在 QT/C++ 中创建一个自定义组合框模型来显示项目并让我选择项目作为相关类而不是字符串?

问题描述

我希望能够使用 C++ 在 QT 中创建一个组合框,该组合框适用于模型(qabstractitemmodel 或 QAbstractListModel - 在本例中为后者),但它适用于实际对象,而不仅仅是 QString 作为认值。这是我的模型:

// H file
#pragma once

#include <QAbstractListModel>
#include <QList>
#include "Test.h"

using net::draconia::test::model::Test;

namespace net
{
    namespace draconia
    {
        namespace test
        {
            namespace ui
            {
                namespace model
                {
                    class TestModel : public QAbstractListModel
                    {
                        QList<Test> mLstModel;
                    public:
                        TestModel();
                        virtual QVariant data(const QModelIndex &index,int role = Qt::displayRole) const;
                        QList<Test> &getModel();
                        virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
                    };
                }
            }
        }
    }
}

// cpp
#include <QtDebug>
#include "TestModel.h"

using namespace net::draconia::test::ui::model;

TestModel::TestModel()
    :   QAbstractListModel()
{
    mLstModel.append(Test("English","EN"));
    mLstModel.append(Test("french","FR"));
}

QVariant TestModel::data(const QModelIndex &index,int role) const
{
    Q_UNUSED(role);

    qDebug() << index;
 
    if(index.isValid())
        {
       QVariant retVal;

        retVal.setValue(const_cast<TestModel &>(*this).getModel()[index.row()]);
 
        return(retVal);
        }
    else
        return(QVariant());
}
 
QList<Test> &TestModel::getModel()
{
    return(mLstModel);
}

int TestModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
 
    qDebug() << "There are " << const_cast<TestModel &>(*this).getModel().count() << " rows";

    return(const_cast<TestModel &>(*this).getModel().count());
 }

我不知道问题是否存在 - 这是此组合框所基于的 Test 类的代码。正如您将看到的,它被声明为元类型:

// H file
#pragma once

#include <QString>
#include <QVariant>

namespace net
{
    namespace draconia
    {
        namespace test
        {
            namespace model
            {
                class Test
                {
                    QString msLanguage,msRegion;
                public:
                    test();
                    Test(const QString &sLanguage,const QString &sRegion);
                    Test(const Test &refcopy);
                    ~test();

                    QString &getLanguage() const;
                    QString &getRegion() const;
                    void setLanguage(const QString &sLanguage);
                    void setRegion(const QString &sRegion);

                    Test &operator=(const Test &refcopy);
                    bool operator==(const Test &refOther) const;
                    bool operator!=(const Test &refOther) const;
                    operator QString() const;

                    QString toString() const;
                };
            }
        }
    }
}

Q_DECLARE_MetaTYPE(net::draconia::test::model::Test);

// CPP file
#include "Test.h"

using namespace net::draconia::test::model;

Test::test()
{ }

Test::Test(const QString &sLanguage,const QString &sRegion)
    :   msLanguage(sLanguage),msRegion(sRegion)
{ }

Test::Test(const Test &refcopy)
    :   Test(refcopy.getLanguage(),refcopy.getRegion())
{ }

Test::~test()
{ }

QString &Test::getLanguage() const
{
    return(const_cast<Test &>(*this).msLanguage);
}

QString &Test::getRegion() const
{
    return(const_cast<Test &>(*this).msRegion);
}

void Test::setLanguage(const QString &sLanguage)
{
    msLanguage = sLanguage;
}

void Test::setRegion(const QString &sRegion)
{
    msRegion = sRegion;
}

Test &Test::operator=(const Test &refcopy)
{
    setLanguage(refcopy.getLanguage());
    setRegion(refcopy.getRegion());

    return(*this);
}

bool Test::operator==(const Test &refOther) const
{
    return  (   (getLanguage() == refOther.getLanguage())
        &&  (getRegion() == refOther.getRegion()));
}

bool Test::operator!=(const Test &refOther) const
{
    return(!operator==(refOther));
}

Test::operator QString() const
{
    return(toString());
}

QString Test::toString() const
{
    return(getLanguage() + "(" + getRegion() + ")");
}

从我在调试语句中看到的情况来看,它正在输入 rowCount 并告诉我有 2 行,并且它正在输入数据方法两次以打印行,但没有打印任何内容。这是简单窗口的代码(我根本不使用 QML - 从来没有也永远不会 - 我认为它很懒!):

// H file
#pragma once

#include <QComboBox>
#include <QMainWindow>

namespace net
{
    namespace draconia
    {
        namespace test
        {
            namespace ui
            {
                class TestMainWindow : public QMainWindow
                {
                    Q_OBJECT

                    QComboBox *mCboTest;
                protected:
                    QComboBox *getTestComboBox();
                    void initControls();
                    void initwindow();
                public:
                    TestMainWindow(QWidget *parent);
                    ~TestMainWindow();
                };
            }
        }
    }
}

// CPP file
#include <QHBoxLayout>
#include "TestMainWindow.h"
#include "TestModel.h"

using namespace net::draconia::test::ui;
using net::draconia::test::ui::model::TestModel;

QComboBox *TestMainWindow::getTestComboBox()
{
    if(mCboTest == nullptr)
        {
        mCboTest = new QComboBox(this);

        mCboTest->setModel(new TestModel());
        }

    return(mCboTest);
}

void TestMainWindow::initControls()
{
    QLayout *layout = new QHBoxLayout(this);

    layout->addWidget(getTestComboBox());

    setLayout(layout);
}

void TestMainWindow::initwindow()
{
    setSizePolicy(QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));

    initControls();
}

TestMainWindow::TestMainWindow(QWidget *parent)
    :   QMainWindow(parent),mCboTest(nullptr)
{
    initwindow();
}

TestMainWindow::~TestMainWindow()
{ }

如果必须的话,我会将代码包含到 Application 类和我的 main.cpp 文件中,但这些是重要的 - 其余的是样板代码。如果您质疑命名空间 - 我总是包含命名空间 - 它可以防止代码感染全局命名空间,即使在示例中也是如此。

对于要显示的组合框项目,我在代码中省略了什么?我从一个更大的项目中复制了大部分代码,这是我真正遇到问题的地方,但它在这里发生太幸运了,所以我可以展示它。在更大的项目中,我有观察者类,它们从组合框中检索选定的对象,并将它们“用作”对象类本身。我从 Java Swing 得到这个,对于要打印的每个项目,组合框模型项目将自动称为 ToString() - 这里似乎并非如此。我想也许它会尝试转换为 QString ,但它甚至没有这样做。我被难住了。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)