[Solved]Why item is appended two times and more?



  • Hi, I am facing very "strange behaviours" that I don't understand. Questions follow after my code:
    @
    Ordre::Ordre(FenPrincipale *FenPr, QWidget *parent) : QWidget (parent)
    {
    principalefen = FenPr;
    model = new QStandardItemModel;

    QObject::connect(principalefen, SIGNAL(OrdreW1()), this, SLOT(OrdreWidget1()));
    QObject::connect(principalefen, SIGNAL(OrdreW2()), this, SLOT(OrdreWidget2()));
    QObject::connect(principalefen, SIGNAL(OrdreW3()), this, SLOT(OrdreWidget3()));
    

    }

    void Ordre::TroisiemeLigneCheck()
    {
    if(model->item(0,2)!=0) //If the 3rd column is full.
    { model->removeColumn(0); }
    }

    void Ordre::OrdreWidget1()
    {
    TroisiemeLigneCheck();
    widget1= new QStandardItem(tr("widget1"));
    if(!widget1->index().data().isValid())
    { model->appendColumn(QList<QStandardItem*>() << widget1); }
    }

    void Ordre::OrdreWidget2()
    {
    TroisiemeLigneCheck();
    widget2= new QStandardItem(tr("widget2"));
    if(!widget2->index().data().isValid())
    { model->appendColumn(QList<QStandardItem*>() << widget2); }

    void Ordre::OrdreWidget3()
    {
    TroisiemeLigneCheck();
    widget3= new QStandardItem(tr("widget3"));
    if(!widget3->index().data().isValid())
    { model->appendColumn(QList<QStandardItem*>() << widget3); }
    }
    @
    1)Why some items are appended two times or more in the model when I enter the slot just once?
    2)If I enter in one of the different slots once, at the second attempt items will not be appended since the condition will be false, right?
    3)If the previous question is right, why items are still appended then?
    4)How append once an item which has been appended once? (as you can notice, i delete them at least once but face my first question)

    Thanks



  • Whenever you call
    @widget->index()@
    you should get an invalid index, since your previously created QStandardItem does not belong to any model yet. Therefore calling
    @data().isValid()@
    should also always return false.

    This answers number 2: You are wrong (which answers number 3), it seems you should read about "QModelIndex":http://qt-project.org/doc/qt-5/qmodelindex.html and "QStandardItem":http://qt-project.org/doc/qt-5/qstandarditem.html a bit more.

    You might have wanted to do something like this:
    @Ordre::Ordre(FenPrincipale *FenPr, QWidget *parent) : QWidget (parent), widget1(0), widget2(0), widget3(0) //initialize your pointers to be safe

    ...

    void Ordre::OrdreWidget1()
    {
    TroisiemeLigneCheck();
    if(widget1 == 0) //don't check for data but for the item itself
    {
    widget1= new QStandardItem(tr("widget1"));
    model->appendColumn(QList<QStandardItem*>() << widget1);
    }
    }@

    If your slots are called more than once even though they shouldn't be, maybe your triggering signal is emitted more than once, you should double check that.

    And I foresee another problem:
    @model->appendColumn(QList<QStandardItem*>() << widget1);@
    This will cause crashes if you have more than one row in your model. You only initialize the first item of that new column, leaving all the other items in the same column point to NULL and, should they be accessed by anybody, crash your program.

    Regarding question 4: I don't see you delete anything. Either your forgot to paste some code or you are wrong here.



  • Hi theEclaw,
    Thanks a lot for your accurate and complete answers. Indeed my program works better with your code, I mean that items are not appended twice or more at the first attempt. However I still face my question 4: when I attempt to append them a second time, items are appended twice. If I attempt a 3rd time, items will be appended 3 times, so and so.

    1. do you think the problem is coming from the signals or the model?
      2)some items are deleted once through my methode "void Ordre::TroisiemeLigneCheck()". Do you agree that "model->removeColumn(0);" delete the 1st column and consequently delete the item inside it? If you don't agree please let me know what I am doing wrong.


  • I think the code you are showing here is "fine". It looks terrible, but it should work as intended. And if you want to know if your slot is actually called twice, use a debugger! If it is, then check if the corresponding signal is emitted twice, too. If so, that's where your problem comes from.

    1. "QAbstractItemModel::removeColumn":http://qt-project.org/doc/qt-5/qabstractitemmodel.html#removeColumn does remove the column, yes. I am not sure how QStandardItemModel handles that since it also has a header. Maybe you should try to remove the column and the corresponding header section:
      @model->removeColumn(0);
      model->takeHorizontalHeaderItem(0);//item should be NULL, so delete might be a bad idea@

    But I am just guessing here. Judging from your code there is a good probability that there is an outside mistake you made, you should really just use a debugger and look what your code actually does.



  • Thank you very much for your help and advices thEClaw. You were right, the problem was coming from another part of my code. More accurately I had to "reset" (with some new and DeleteOnClose) another used class somewhere in my program. Now it rocks :D

    1. Apparently QStandardItemModel's methode "removeColumn" seems enough to do the job. I did not need to remove any header.

    Now I can keep developing "serenely" XD

    Thanks again.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.