3

I am really stuck at the moment.. My Application can create (animation) frames with a click, these frames can either be moved, deleted or edited. I want some kind of right-click context menu to delete them.

My attempt now is creating a QListWidget, and insert QListWidgetItems (the frames) in there. I can put these Items in there, but ofcourse i have no idea on how to store the frames then.

I tried to make a new class, derived from QListWidgetItem like this:

    #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();
    };

This would actually work, but the itemClicked() signal does not trigger anymore.

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

If I change the parameter of itemClicked(QListWidgetItem* item) to itemClicked(FrameItem* item) the signal does not fire anymore.

Do I need to overwrite the itemClicked() slot? If yes, how? Is there a better approach to store much data, and give them a right-click contextmenu?

Gizmo
  • 1,990
  • 1
  • 24
  • 50
Captain GouLash
  • 1,257
  • 3
  • 20
  • 33

2 Answers2

3

The present slot's arguments must match the signal's arguments. So, you can't use a slot with FrameItem parameter. Use this:

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

You need to cast QListWidgetItem to FrameItem. You're allowed to do this only if you are sure that it's really FrameItem object. You can't use qobject_cast since QListWidgetItem doesn't inherit QObject, but it's still better to use static_cast instead of reinterpret_cast. If you insert only FrameItem items in your list, it would be OK. In other cases the perfect choice would be dynamic_cast because it returns null pointer if the object is not actually FrameItem. But it may not work if you use dynamic linking.

Aside of this, subclassing QListWidgetItem is not recommended. As the documentation says, QListWidget::setItemWidget should be used to display static content using custom Widgets, and QListView and QItemDelegate should be used in more complex cases.

Pavel Strakhov
  • 39,123
  • 5
  • 88
  • 127
1

If you change the function signature, the signal wont trigger. The solution is much simpler, just receive a QListWidgetItem * and reinterpret_cast it to a FrameItem.

As long as you NEVER insert anything in the list that it's not a FrameItem, you will be safe.

Diego Sánchez
  • 539
  • 2
  • 12
  • Like this ?connect(listWidget,SIGNAL(itemClicked(QListWidgetItem*)),this,SLOT(itemClicked(QListWidgetItem*))); and in the slot this: FrameItem* fi= reinterpret_cast(&item); – Captain GouLash Jun 05 '13 at 08:13
  • @Amazonasmann: That's it, only that you shouldn't be using the address of item: FrameItem* fi = reinterpret_cast(Item); – Diego Sánchez Jun 05 '13 at 08:16
  • ok, now i can access the functions of FrameItem..however, item->setText() is working just fine...but when i do a item->setId(20) and in the slot i make a item->getId() the result is not not 20 but -1414812757 ..any ideas? – Captain GouLash Jun 05 '13 at 08:30
  • @Amazonasmann Is your `setId(int id)` function assigning a value to the correct variable? – thuga Jun 05 '13 at 08:37
  • maybe i should really do a qobject_cast ? but i did not figure out yet how to do it... qobject_cast(item) does not work... – Captain GouLash Jun 05 '13 at 08:44