QPushButton will not update/repaint after button press



  • alt text

    I have three stacks represented as QPushButtons. What I want to do is, when you click on the second pole, the first pole loses it's top disk, and that disk is stacked onto the empty second pole.

    The problem I am having is that, after I click on the second pole, the first pole repaints and loses it's top disk, but the second pole does not gain the lost disk. I have tried forcing it to do so with repaint(), but I have had no luck.

    Each pole is represented in an inherited QWidget class. Each pole contains a stack of disks (which themselves are represented as an inherited QWidget class). I initialize the poles like so at the programs launch:

        poles[0] = new pole(0, ui->spinBox->value(), ui->stack_one);
        poles[1] = new pole(1, 0, ui->stack_two);
        poles[2] = new pole(2, 0, ui->stack_three);
    
    ...
    //pole constructor
        this->resize(parent->geometry().width(), parent->geometry().height());
        n = num;
        numDisks = count;
    
        int j = numDisks;
        for (int i = 0; i < numDisks; i++)
        {
            stack.push_back(new disk(j, i, this, parent));
            j--;
        }
    

    When the second pole is clicked, it triggers it's slot function and proceeds to call function after function to move the disk.

    void TowerOfHanoi::on_stack_two_clicked()
    {
        move.moveToStack(poles[1]);
    }
    ...
    void moveHandler::moveToStack(pole* toStack)
    {
        toStack->put(activePole->take());
    }
    ...
    disk* pole::take()
    {
        disk* topDisk = NULL;
    
        if (!stack.empty())
        {
            topDisk = stack.back();
            stack.pop_back();
        }
    
        return topDisk;
    }
    ...
    bool pole::put(disk* d)
    {
        bool success = false;
    
        if (stack.empty() || stack.back()->Size() > d->Size())
        {
            d->setPolePos(this, stack.capacity());
            d->setParent(this->parentWidget());
            stack.push_back(d);
            d->repaint();
            d->parentWidget()->repaint();
            d->parentWidget()->parentWidget()->repaint();
            success = true;
        }
    
    
        return success;
    }
    
    

    After debugging thoroughly, I'm confident the taken disk is put into the second pole's stack of disks. What I find weird is that, using QDebug, I found that only the paintEvent()'s of the disks on top of the first pole are triggered automatically after

      d->setParent(this->parentWidget());
    

    but not the disk on the second pole.

    Could someone help me figure out why or how to repaint the other pole's? I'm new to Qt so I apologize if the answer if obvious.


  • Qt Champions 2016

    hi and welcome
    The code looks fine and well structured so I assume the stack part is working as intended. Nothing obvious :)

    If you from start give pole 2 some disks, they are painted as expected?

    To test if its a repaint issue, try cover the app with another window and
    remove it again. that should trigger some updates.



  • @mrjj

    If I add disks from the beginning, they do paint:

        poles[0] = new pole(0, ui->spinBox->value(), ui->stack_one);
        poles[1] = new pole(1, 4, ui->stack_two);
        poles[2] = new pole(2, 6, ui->stack_three);
    

    alt text

    Covering up the window with other windows does not seem to paint the disks on the pole.

    Edit: I think it's worth mentioning that I have the following piece of code in disk's overriden paintEvent:

    qDebug() << "Disk paintEvent triggered " << on->parentWidget()->accessibleName() << size;
    

    and the output I get for the default launch is :

    Disk paintEvent triggered  "s1" 8
    ...
    Disk paintEvent triggered  "s1" 1
    

    and when I fill up the other two poles at startup:

    Disk paintEvent triggered  "s2" 4
    ...
    Disk paintEvent triggered  "s2" 1
    Disk paintEvent triggered  "s3" 6
    ...
    Disk paintEvent triggered  "s3" 1
    ...
    Disk paintEvent triggered  "s1" 1
    

    so the paintEvents are being triggered for disks on on other pole's at startup.



  • Ah I managed to fix it!

    The problem was that, after setting a new parent for the disk, it turns the Widget invisible and all I had to do was use show() to make it reappear again. I have to be more attentive with the documentation next time.

    Thanks for trying to help me!


  • Qt Champions 2016

    @jaramos2409
    hehe good found
    I was about to ask about show as normally
    widget->update()/repaint() is enough for it to redraw


Log in to reply
 

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