3

我现在真的被困住了。我的应用程序可以通过单击创建(动画)帧,这些帧可以移动、删除或编辑。我想要某种右键单击上下文菜单来删除它们。

我现在的尝试是创建一个 QListWidget,并在其中插入 QListWidgetItems(框架)。我可以把这些物品放在那里,但是我当然不知道如何存储框架。

我试图创建一个从 QListWidgetItem 派生的新类,如下所示:

    #pragma once

    #include <qobject.h>
    #include <QtGui>
    #include <Frame.h>

    class FrameItem : public QListWidgetItem
    {
    public:
        FrameItem();
        Frame frame;
        void setFrame(Frame f);
        Frame getFrame();
        int id;
        void setId(int id);
        int getId();
    };

这实际上会起作用,但 itemClicked() 信号不再触发。

void itemClicked(QListWidgetItem* item)
{   
    std::cout << item->text().toStdString() << std::endl;
};

如果我将 itemClicked(QListWidgetItem* item) 的参数更改为 itemClicked(FrameItem* item),则信号不再触发。

我需要覆盖 itemClicked() 插槽吗?如果是,如何?是否有更好的方法来存储大量数据,并为它们提供右键单击上下文菜单?

4

2 回答 2

3

当前插槽的参数必须与信号的参数匹配。因此,您不能使用带FrameItem参数的插槽。用这个:

void itemClicked(QListWidgetItem* item) {
  FrameItem* frameItem = static_cast<FrameItem*>(item);
  //...
}

您需要转换QListWidgetItemFrameItem. 只有当您确定它确实是FrameItem对象时,您才可以这样做。你不能使用qobject_castsince QListWidgetItemdoesn't inherit QObject,但它仍然更好地使用static_cast,而不是reinterpret_cast更好。如果您只FrameItem在列表中插入项目,那就没问题了。在其他情况下,完美的选择是dynamic_cast因为如果对象实际上不是,它会返回空指针FrameItem。但如果您使用动态链接,它可能不起作用。

除此之外,QListWidgetItem不推荐子类化。正如文档所说,QListWidget::setItemWidget应该使用自定义小部件来显示静态内容,QListView并且QItemDelegate应该在更复杂的情况下使用。

于 2013-06-05T08:46:59.983 回答
1

如果更改函数签名,信号将不会触发。解决方案要简单得多,只需接收一个 QListWidgetItem * 并将其重新解释为 FrameItem。

只要您从不在列表中插入任何不是 FrameItem 的内容,您就会很安全。

于 2013-06-05T08:00:49.940 回答