【问题标题】:Using QTreeWidgetItems setData to store a QStackedWidget or QVariant使用 QTreeWidgetItems setData 存储 QStackedWidget 或 QVariant
【发布时间】:2018-02-23 17:39:49
【问题描述】:

我正在尝试制作一个 QTreeWidget,使每一行都包含一系列组合框。根据用户与组合框的交互方式,我希望某些组合框成为行编辑,一些成为按钮。

有人建议here QStackedWidget 可以满足我的需求,并且它做得很好,除了现在我需要一种方法来更改包含组合框的 QStackedWidget 旁边的 QStackedWidget,该组合框向我发送 indexChanged 信号。 (基本上我想改变相邻的QStackWidgets索引)

我认为我可以使用 setData 将 QStackWidget 简单地存储在 childItem 中,然后在 indexChanged 插槽中检索它,但由于某种原因,QStackWidget 似乎未设置为 childItems 数据。

感谢任何帮助。

这是我最初设置 QTreeWidget 及其项目的地方

    QTreeWidgetItem *childItem = new QTreeWidgetItem(itemParent);



    QVariant itemParentVariant,widgetParentVarient;
    widgetParentVarient.setValue(widgetParent);
    itemParentVariant.setValue(itemParent);
    QList<QVariant> stackWidgetList;
    uint cycleSetup;
    for(cycleSetup = 0;cycleSetup < methodBlocks.at(rowType).size()+2;cycleSetup++)
    {

            QComboBox *itemComboBox = new QComboBox;
            itemComboBox->setProperty("rowType", rowType);
            itemComboBox->setProperty("row", 0);
            itemComboBox->setProperty("column",cycleSetup);
            itemComboBox->setProperty("widgetParent",widgetParentVarient);
            itemComboBox->setProperty("itemParent",itemParentVariant);
            itemComboBox->addItems(methodBlocks.at(0).at(cycleSetup));
            QObject::connect(itemComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnComboIndexChanged(const QString&)));
            QLineEdit *itemLineEdit = new QLineEdit;
            QPushButton *itemButton = new QPushButton;
            itemButton->setText("Reset");
            QComboBox *timeComboBox = new QComboBox;
            timeComboBox->setProperty("rowType", rowType);
            timeComboBox->setProperty("row", 0);
            timeComboBox->setProperty("column",cycleSetup);
            timeComboBox->setProperty("widgetParent",widgetParentVarient);
            timeComboBox->setProperty("itemParent",itemParentVariant);
            timeComboBox->addItems(QString("Seconds;MilliSeconds;Reset").split(";"));
            QStackedWidget *masterItemWidget = new QStackedWidget;
            masterItemWidget->addWidget(itemLineEdit);
            masterItemWidget->addWidget(itemComboBox);
            masterItemWidget->addWidget(itemButton);
            masterItemWidget->addWidget(timeComboBox);
            masterItemWidget->setCurrentIndex(1);
            QVariant stackParent;
            stackParent.setValue(masterItemWidget);
            itemComboBox->setProperty("stackParent",stackParent);
            childItem->setData(0,Qt::UserRole,stackParent);
            stackWidgetList.push_back(stackParent);
            widgetParent->setItemWidget(childItem,cycleSetup,masterItemWidget);
            itemParent->addChild(childItem);
    }

这是在我试图检索数据的插槽内(QStackWidget)

                QStackedWidget *itemMaster = combo->property("stackParent").value<QStackedWidget*>(); //this works
                itemMaster->setCurrentIndex(0);
                QTreeWidget *widgetParent = combo->property("widgetParent").value<QTreeWidget*>();

                QTreeWidgetItem *parentItem = combo->property("itemParent").value<QTreeWidgetItem*>();
                QTreeWidgetItem *childItem = new QTreeWidgetItem(parentItem);


                QList<QVariant> stackList = childItem->data(0,Qt::UserRole).value<QList<QVariant>>(); //this doesnt
                QStackedWidget *itemsibMaster = childItem->data(0,Qt::UserRole).value<QStackedWidget*>(); //neither does this
                itemsibMaster->setCurrentIndex(2);

编辑:

我试过这样设置数据

            QFrame *stackFrame = new QFrame;
            QStackedWidget *masterItemWidget = new QStackedWidget(stackFrame);
            masterItemWidget->addWidget(itemLineEdit);
            masterItemWidget->addWidget(itemComboBox);
            masterItemWidget->addWidget(itemButton);
            masterItemWidget->addWidget(timeComboBox);
            masterItemWidget->setCurrentIndex(1);
            QVariant stackParent;
            stackParent.setValue(masterItemWidget);
            itemComboBox->setProperty("stackParent",stackParent);
            QVariant frameVariant;
            frameVariant.setValue(stackFrame);
            childItem->setData(0,Qt::UserRole,frameVariant);
            stackWidgetList.push_back(stackParent);
            widgetParent->setItemWidget(childItem,cycleSetup,masterItemWidget);
            itemParent->addChild(childItem);

然后像这样检索它

                QStackedWidget *itemMaster = combo->property("stackParent").value<QStackedWidget*>();
                itemMaster->setCurrentIndex(0);
                QTreeWidget *widgetParent = combo->property("widgetParent").value<QTreeWidget*>();

                QTreeWidgetItem *parentItem = combo->property("itemParent").value<QTreeWidgetItem*>();
                QTreeWidgetItem *childItem = new QTreeWidgetItem(parentItem);


                QFrame *frameObject = childItem->data(0,Qt::UserRole).value<QFrame*>();
                //QList<QVariant> stackList = childItem->data(0,Qt::UserRole).value<QList<QVariant>>();
                QStackedWidget *itemFrameMaster = frameObject->findChild<QStackedWidget*>();
                if(itemFrameMaster)
                {
                    qDebug() << "itemFrame Exists";

                }
                else
                {
                    qDebug() << "itemFrame is NULL";//It goes to here
                }

所以我仍然无法获得所需的功能。

【问题讨论】:

  • 不要将QTreeWidget 用于如此复杂的事情。将 QTreeView 与模型和项目委托一起使用。它更加灵活,让您的代码易于管理。
  • 老实说,我确实尝试过使用 QTreeView,但是我对没有委托类而是树项和树视图类的示例感到有些困惑。我会尝试再试一次,我开始认为这可以通过 QTreeView 并仅使用项目委托类来完成。

标签: c++ qtreewidget qtreewidgetitem qvariant qstackedwidget


【解决方案1】:

检查它是否有效。

作为从QFrame 派生的堆叠小部件QStackedWidget,创建一个框架对象并将您的堆叠小部件添加到其中。将框架设置为您的子项。

QFrame *stackFrame = new QFrame(Parent);

QStackedWidget *masterItemWidget  = new QStackedWidget(stackFrame);

在查询框架的第一个查询并从中获取堆叠的小部件子项时。

QStackedWidget *stackedWidget = FrameObject->findChild<QStackedWidget *>();

【讨论】:

  • 所以我只是尝试了这个 QFrame stackFrame = new QFrame(childItem); QStackedWidget *masterItemWidget = new QStackedWidget(stackFrame);但这给了我一些关于没有函数调用的错误 (QFrame::QFrame(QTreeWidgetItem&)) 我错过了什么吗?
  • 查看编辑,我不确定我是否误解了您的建议,但到目前为止还没有运气。
【解决方案2】:

好的,所以我设法获得了我所追求的功能,所以如果其他人试图这样做,这就是修复。

基本上我之前所做的一切都是正确的,除了一个错误。

在检索存储在组合框子项中的数据时,我最初在这里得到了那个子项。

            QTreeWidgetItem *parentItem = combo->property("itemParent").value<QTreeWidgetItem*>();
            QTreeWidgetItem *childItem = new QTreeWidgetItem(parentItem);

问题在于,由于 parentItem 有多个孩子(我想在这种情况下最少是两个孩子),我没有引用正确的孩子。此问题已通过创建自定义组合框属性得到解决,该属性包含子项而不是父项(父项可以更准确地从父项派生,反之亦然)。

现在我用组合框项填充 QTreeWidget 的位置如下所示。

    QTreeWidgetItem *childItem = new QTreeWidgetItem(itemParent);

    QVariant childItemVariant,widgetParentVarient;
    widgetParentVarient.setValue(widgetParent);
    childItemVariant.setValue(childItem);
    uint cycleSetup;
    for(cycleSetup = 0;cycleSetup < methodBlocks.at(rowType).size();cycleSetup++)
    {
        if(cycleSetup < methodBlocks.at(rowType).size())
        {
            QComboBox *itemComboBox = new QComboBox;
            itemComboBox->setProperty("rowType", rowType);
            itemComboBox->setProperty("row", 0);
            itemComboBox->setProperty("column",cycleSetup);
            itemComboBox->setProperty("widgetParent",widgetParentVarient);
            itemComboBox->setProperty("childItem",childItemVariant);
            itemComboBox->addItems(methodBlocks.at(0).at(cycleSetup));
            QObject::connect(itemComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnComboIndexChanged(const QString&)));
            QLineEdit *itemLineEdit = new QLineEdit;

            QFrame *stackFrame = new QFrame;
            QStackedWidget *masterItemWidget = new QStackedWidget(stackFrame);
            masterItemWidget->addWidget(itemLineEdit);
            masterItemWidget->addWidget(itemComboBox);
            //masterItemWidget->addWidget(timeComboBox);
            masterItemWidget->setCurrentIndex(1);
            QVariant stackParent;
            stackParent.setValue(masterItemWidget);
            itemComboBox->setProperty("stackParent",stackParent);
            itemComboBox->setProperty("cycleSetupIT",cycleSetup);
            QVariant frameVariant;
            frameVariant.setValue(stackFrame);
            childItem->setData(cycleSetup,Qt::UserRole,stackParent);
            widgetParent->setItemWidget(childItem,cycleSetup,masterItemWidget);
            itemParent->addChild(childItem);
        }

    }

}

我从 childItem(包含组合框)获取数据的插槽中的代码如下所示。

                QTreeWidget *widgetParent = combo->property("widgetParent").value<QTreeWidget*>();
                widgetParent->setColumnCount(6);
                QTreeWidgetItem *childItem = combo->property("childItem").value<QTreeWidgetItem*>();
                QTreeWidgetItem *parentItem = childItem->parent();

                int rowType = combo->property("rowType").toInt();
                int cycleIT = combo->property("cycleSetupIT").toInt();
                int offset = 0;

                QStackedWidget *itemFrameMaster = childItem->data(cycleIT+1,Qt::UserRole).value<QStackedWidget*>();
                itemFrameMaster->setCurrentIndex(0);

希望这会有所帮助。此外,如果有人知道如何获取 QStandardItem::data() 中的数据项数量,那将是很棒的,尽管不是超级关键。

干杯!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 2015-12-19
    相关资源
    最近更新 更多