Results 1 to 9 of 9

Thread: QItemDelegate with QTextEdit

  1. #1
    Join Date
    Apr 2013
    Posts
    15
    Thanks
    2
    Qt products
    Qt5
    Platforms
    MacOS X

    Default QItemDelegate with QTextEdit

    Hi everyone,
    I'm fairly new to Qt so i'm pretty sure i'm taking the long way around to solv a very simple problem. Anyhow, what I want to do is to obtain is a QListWidget in which under every image is a description of the image, which can be edited in a QTextBox, thus allowing multiple lines and wordwrap.
    What I did was to create a new QItemDelegate subclassing from QStyledItemDelegate (ItemDelegate), and then I created a editor subclassing from QWidget (DelegateWidget).
    The problem I am having right now is that when I pass the QModelIndex to the DelegateWidget, I can't get the Image from the DecorativeRole.
    Can someone tell me what I'm doing wrong, or if there is an easier way, as I really think I'm just making a mess.
    P.S.
    I was actually thinking I might just create a ScrollArea from scratch and just add the images and text to the ScrollArea, but then I'd probably hav to reimplement the dragging etc.

    QItemDelegate
    Qt Code:
    1. ItemDelegate::ItemDelegate(QObject *parent)
    2. : QStyledItemDelegate(parent)
    3. {
    4. }
    5.  
    6. QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index ) const
    7. {
    8.  
    9.  
    10. return new DelegateWidget(parent, index);
    11. }
    12.  
    13. void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    14. {
    15.  
    16. static_cast<DelegateWidget*>(editor)->setText(index.data(Qt::EditRole).toString());
    17. }
    18.  
    19. void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const
    20. {
    21.  
    22. QString value=static_cast<DelegateWidget*>(editor)->GetText();
    23.  
    24. model->setData(index, value, Qt::EditRole);
    25. }
    26.  
    27. void ItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    28. {
    29. static_cast<DelegateWidget*>(editor)->setGeometry(option.rect);
    30. }
    To copy to clipboard, switch view to plain text mode 

    DelegateWidget
    Qt Code:
    1. DelegateWidget::DelegateWidget(QWidget *parent, const QModelIndex &index) :
    2. QWidget(parent)
    3. ,TextEditBox(new QTextEdit)
    4. ,mText(index.data().toString())
    5. ,ImgDisplay(new QLabel)
    6. {
    7.  
    8. QVBoxLayout *vLayout =new QVBoxLayout(this);
    9. QPixmap px=static_cast<QPixmap>(index.data(Qt::DecorationRole));
    10. ImgDisplay->setPixmap(px);
    11. mText=index.data(Qt::EditRole).toString();
    12. TextEditBox->setText(mText);
    13. vLayout->addWidget(ImgDisplay);
    14. vLayout->addWidget(TextEditBox);
    15. }
    16.  
    17. QString DelegateWidget::GetText() const {
    18. return mText;
    19. }
    20.  
    21.  
    22. void DelegateWidget::setText(const QString & text){
    23. mText=text;
    24. TextEditBox->setText(text);
    25. }
    26.  
    27. void DelegateWidget::updateText(void){
    28. mText = TextEditBox->toPlainText();
    29. //emit textChanged(mText);
    30. }
    To copy to clipboard, switch view to plain text mode 

    Main
    Qt Code:
    1. int main(int argc, char *argv[])
    2. {
    3. QApplication a(argc, argv);
    4.  
    5. QWidget window;
    6.  
    7. QLabel* title = new QLabel("Custom widgets on a QListWidget");
    8. title->setAlignment(Qt::AlignHCenter);
    9.  
    10. QListWidget* list = new QListWidget;
    11. list->setItemDelegate(new ItemDelegate(list));
    12. list->setViewMode(QListView::IconMode);
    13. list->setIconSize(QSize(200,200));
    14. list->setWrapping(false);
    15.  
    16.  
    17. first->setText("1");
    18. first->setIcon(QPixmap("/Users/Nick/Desktop/chocolate.jpeg"));
    19. first->setFlags (first->flags () | Qt::ItemIsEditable);
    20. list->addItem(first);
    21.  
    22. second->setText("2");
    23. second->setIcon(QIcon("/Users/Nick/Desktop/chocolate.jpeg"));
    24. second->setFlags (second->flags () | Qt::ItemIsEditable);
    25. list->addItem(second);
    26.  
    27. QVBoxLayout* layout = new QVBoxLayout(&window);
    28. layout->addWidget(title);
    29. layout->addWidget(list);
    30. window.setLayout(layout);
    31.  
    32. window.show();
    33.  
    34. return a.exec();
    35. }
    To copy to clipboard, switch view to plain text mode 

    I got most of this code from another post somewhere in the forum (can't find it anymore though)
    Thank you

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: QItemDelegate with QTextEdit

    Qt::DecorationRole returns QIcon (in the QVariant) not QPixmap, the correct way will be
    Qt Code:
    1. ...
    2. QPixmap px = qvariant_cast<QIcon>(index.data(Qt::DecorationRole)).pixmap(200);
    3. ...
    To copy to clipboard, switch view to plain text mode 
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  3. #3
    Join Date
    Apr 2013
    Posts
    15
    Thanks
    2
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QItemDelegate with QTextEdit

    What a coincidence, you are the person who posted the code in the first place!!!
    Thank you very much, I had already tried that but for some reason I had uses static_cast instead of qvariant_cast.
    Is there any way to get the original size of the image in the QListWidget, so I can get the editor to cover the item while editing (kind of like when I rename a file, so the QTextEdit would just expand below).
    Furthermore whenever I de-comment
    Qt Code:
    1. ...
    2. emit textChanged(mText);
    3. ...
    To copy to clipboard, switch view to plain text mode 
    I get the following error:
    symbol(s) not found for architecture x86_64
    Even though I'm not sure why you implemented that method in the first place. I think it's needed to update the model data but i'm not sure how the two are connected. I've been reading around and if i'm not mistaken I should be the equivalent of the finishedEditing() which I should then connect to the commitAndClose() (parallel taken fromt the track editor example)
    Could you expand a bit on that part.
    Thank you very much

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: QItemDelegate with QTextEdit

    What a coincidence, you are the person who posted the code in the first place!!!
    The post you took the code from has sightly different requirement, take that into account.

    Is there any way to get the original size of the image in the QListWidget, so I can get the editor to cover the item while editing (kind of like when I rename a file, so the QTextEdit would just expand below).
    Use QIcon::availableSizes(), and take the first size.

    Furthermore whenever I de-comment
    Qt Code:
    1. ...
    2. emit textChanged(mText);
    3. ...
    To copy to clipboard, switch view to plain text mode 
    I get the following error:
    symbol(s) not found for architecture x86_64
    Make sure you use Q_OBJECT macro as the first line in the class definition, and make sure you have declared that function as a Qt signal.

    Even though I'm not sure why you implemented that method in the first place. I think it's needed to update the model data but i'm not sure how the two are connected.
    As I said earlier, the code was posted for a different requirement, the requirement was not to save the data into the model until the user clicks the save/apply pushButton explicitly. That is the reason updateText() slot and textChanged(QString) signal were suggested, and as such textChanged() was only provided to extend the functionality if required and has nothing to do with model/view, so just ignore it.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  5. #5
    Join Date
    Apr 2013
    Posts
    15
    Thanks
    2
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QItemDelegate with QTextEdit

    Hi,
    I re-wrote the class to make sure I had understood how everything worked and to make sure there were no errors, and was able to get everything to work except for emitting the commitData fromt he QStyledItemDelegate. For some reason if I add the Q_OBJECT macro at the beginning of the definition I get a "symbol(s) not found for architecture x86_64" error, while if I do not add it it tells me "No such slot QStyledItemDelegate::FinishedEditing.
    Header File
    Qt Code:
    1. #ifndef NEWITEMDELEGATE_H
    2. #define NEWITEMDELEGATE_H
    3. #include <QStyledItemDelegate>
    4. #include <QWidget>
    5. #include <QObject>
    6.  
    7. class newItemDelegate : public QStyledItemDelegate
    8. {
    9. Q_OBJECT
    10. public:
    11. newItemDelegate(QObject *parent = 0);
    12.  
    13. QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const;
    14.  
    15. void setEditorData(QWidget *editor, const QModelIndex &index) const;
    16.  
    17. void setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const;
    18.  
    19. void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
    20.  
    21. private slots:
    22. void FinishedEditing();
    23.  
    24. };
    25.  
    26. #endif // NEWITEMDELEGATE_H
    To copy to clipboard, switch view to plain text mode 

    CPP File
    Qt Code:
    1. #include "newitemdelegate.h"
    2. #include "newdelegatewidget.h"
    3. #include <QStyledItemDelegate>
    4. #include <QWidget>
    5.  
    6. newItemDelegate::newItemDelegate(QObject *parent)
    7. : QStyledItemDelegate(parent)
    8. {
    9. }
    10.  
    11. QWidget * newItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
    12. {
    13.  
    14. newDelegateWidget *editWidget = new newDelegateWidget(parent, index);
    15. connect (editWidget, SIGNAL(lostFocus()),this, SLOT(FinishedEditing()));
    16. return new newDelegateWidget(parent, index);
    17. }
    18.  
    19. void newItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
    20. {
    21. static_cast<newDelegateWidget*>(editor)->SetText(index.data(Qt::EditRole).toString());
    22. }
    23.  
    24. void newItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const
    25. {
    26. QString value=static_cast<newDelegateWidget*>(editor)->GetText();
    27. model->setData(index, value, Qt::EditRole);
    28. }
    29.  
    30. void newItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
    31. {
    32. static_cast<newDelegateWidget*>(editor)->setGeometry(option.rect);
    33. }
    34.  
    35.  
    36. void newItemDelegate::FinishedEditing()
    37. {
    38. newDelegateWidget *editor = qobject_cast<newDelegateWidget *>(sender());
    39. emit commitData(editor);
    40. emit closeEditor(editor);
    41. }
    To copy to clipboard, switch view to plain text mode 
    If i'm not mistaken emitting the commitData should change the value of QModelIndex in the QListWidget

  6. #6
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: QItemDelegate with QTextEdit

    If i'm not mistaken emitting the commitData should change the value of QModelIndex in the QListWidget
    NO. Edited data has to be saved into the Model (QListWidget's Model) in setModelData(), and additional signal / slots are not required.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  7. #7
    Join Date
    Apr 2013
    Posts
    15
    Thanks
    2
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QItemDelegate with QTextEdit

    Ok, so if I connect the signal the widget I made emits when it looses focus, to the slot setModelData() like this:
    Qt Code:
    1. ...
    2. QWidget * newItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,const QModelIndex &index) const
    3. {
    4.  
    5. newDelegateWidget *editWidget = new newDelegateWidget(parent, index);
    6. connect (editWidget, SIGNAL(lostFocus()),this, SLOT(setModelData(editWidget,option,index)));
    7. return new newDelegateWidget(parent, index);
    8. }
    9. ...
    To copy to clipboard, switch view to plain text mode 
    whenever the widget loosed focus it should call the setModelData, and update the information. Still, when I add Q_OBJECT i get the symbols error, while if the macro is not added I get the slot (setModelData()) does not exist. What am I missing?

  8. #8
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: QItemDelegate with QTextEdit

    Ok, so if I connect the signal the widget I made emits when it looses focus, to the slot setModelData() like this:
    First thing setModelData() is not a slot, so you cannot connect it to a signal.
    Second, you need not call setModelDataa(), view will call it when you editing is finished.

    So I repeat, REMOVE SIGNALS AND SLOTS, YOU DON'T NEED THEM, THEY WERE ADDED FOR SOME OTHER REQUIREMENT, this I mentioned in my earlier two posts.
    When you know how to do it then you may do it wrong.
    When you don't know how to do it then it is not that you may do it wrong but you may not do it right.

  9. The following user says thank you to Santosh Reddy for this useful post:

    caster89 (25th April 2013)

  10. #9
    Join Date
    Apr 2013
    Posts
    15
    Thanks
    2
    Qt products
    Qt5
    Platforms
    MacOS X

    Default Re: QItemDelegate with QTextEdit

    Ok, so I had seen the post, but even removing the signals I still couldn't get the model to update when I finished editing, that is why I thought I had to reput the signals. I then realised the problem was that getText() I was returning the QString which did not update, by returning QTextEdit::toPlainText the data is updated.
    Furthermore the reason i got the error when adding Q_OBJECT was that I forgot to delete the moc file, after that I didn't get the error anymore.
    Thank you for your help

Similar Threads

  1. QPushButton and QItemDelegate
    By sawerset in forum Qt Programming
    Replies: 1
    Last Post: 21st May 2009, 22:13
  2. QItemDelegate
    By Alex_123 in forum Qt Programming
    Replies: 1
    Last Post: 12th October 2008, 11:40
  3. Using most of QItemDelegate
    By joshuajcarson in forum Qt Programming
    Replies: 4
    Last Post: 6th October 2008, 16:02
  4. QItemDelegate
    By cyberboy in forum Qt Programming
    Replies: 10
    Last Post: 27th June 2008, 17:41
  5. Replies: 1
    Last Post: 16th February 2007, 07:22

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.