PDA

View Full Version : popup editors for QTreeView and QAbstractItemModel



ctgrund
22nd January 2014, 08:51
Hi,

I am doing fine with QTreeView, abstract models, and delegates.
What I need now is the following: In the tree there is a string and if I would like to edit it there should come something like the ... button. When I click on it the file dialog pops up. Similar things for self written dialogs as table editors ...
I need some hints (signals to check, how to transfer data and so on). A link to a working example would also be enough. But this should be an example where Qt MVC concepts are used.

Thanks a lot!
Thomas

StrikeByte
22nd January 2014, 10:33
You can try doing this (didn't test it)
add this to the delegate class you already have
it does not change the apearance of the string but it will open a filedialog on edit


void ItemDelegate::setModelData(QWidget *editor,
QAbstractItemModel *model, const QModelIndex &index) const
{
//this is for all items in the item model, if you want it only for one column check if index.column() == the column you want the filedialog for

mode.setData(index,QFileDialog::getOpenFileName(), Qt::EditRole) //you need to include <QFileDialog>
}



if you want to change the apreance too then you need to add the special editor in your item delegate createEditor function


QWidget *ItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
return new SpecialEditor(parent); //the special editor needs to be a QWidget or derivative from it
}

ctgrund
22nd January 2014, 10:40
I have the feeling that this solution is at least not complete.
Code 1: ?? setModelData: the QWidget is not used at all. Is this the right position to open up a popup??
Code 2: ?? createEditor: this creates a widget within the tree view. I would like to have it popup.

StrikeByte
22nd January 2014, 10:47
Code 1: yes this is the right position to create a filedialog (if you dont want to change the string appearance in the tree view), the dialog will be created if you start editing a string in the treeview.
Code 2: if you use this method you will have to create a widget that takes care of creating a popup
setModelData will have to call a function in the widget to open the pop up

ctgrund
22nd January 2014, 11:04
Code 1: Isn't setModelData called after editing was done? So I must set isEditable and then only after editing (using editor within the tree) the popup comes up?

anda_skoa
22nd January 2014, 12:46
am doing fine with QTreeView, abstract models, and delegates.
What I need now is the following: In the tree there is a string and if I would like to edit it there should come something like the ... button.

Then your delegate will create a button as the editor widget.



When I click on it the file dialog pops up.

Then you need to connect your button's clicked() signal to a slot that runs the file dialog.

You could have your own button class that does that internally and has a member for the file name, which is set in setEditorData and read in setModelData.
Or using a dynamic property on a normal QPushButton or storing the name elsewhere and accessing it from the slot that shows the dialog.

I would go for a base class that encapsulates the dialog step



class EditorButton : public QPushButton
{
Q_OBJECT

public:
explicit EditorButton( QWidget *parent ) : QPushButton( parent )
{
connect( this, SIGNAL(clicked()), this, SLOT(onClicked()) );
}

void setEditorData( const QVariant &data ); // store data delegate gets in setEditorData
QVariant modelData() const; // return data that setModelData should store.

protected slots:
virtual void onClicked() = 0; // implemented by sub classes
}


EditorButton::setEditorData() could also set the button's text, but you can also do that in the delegate.
It could also be subclass specific, i.e. using QString as the type for file names. depends on where you want to know about which class

Cheers,
_

StrikeByte
22nd January 2014, 12:46
Yes sorry you are right i copied the wrong part
should have copied

bool QAbstractItemDelegate::editorEvent ( QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index ) [virtual]
When editing of an item starts, this function is called with the event that triggered the editing, the model, the index of the item, and the option used for rendering the item.

Mouse events are sent to editorEvent() even if they don't start editing of the item. This can, for instance, be useful if you wish to open a context menu when the right mouse button is pressed on an item.

The base implementation returns false (indicating that it has not handled the event).

for more information read the documentation on QAbstractItemDelegate

did a quick test and this is working


bool ItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
model->setData(index,QFileDialog::getOpenFileName(),Qt::E ditRole); //you need to include <QFileDialog>
return false;
}

ctgrund
22nd January 2014, 12:55
Button will be the editor widget! Everything else I think I can do.
Thanks!