Qt Programm stürzt ab bei verschieben eines Buttons



  • Servus
    Das ist ehrlich gesagt das erste mal, dass ich mich mit einem Problem in C++ an ein Forum wende. Ich hoffe, dass trotzdem alles so passt wie ich es schreibe.

    Folgendes ist das exakte Problem:
    Ich arbeite mit Qt 4 und habe ein Programm geschrieben, welches beim Klick auf einen QPushButton 8 andere erst erstellt und dann um den Hauptbutton herum gruppiert.
    Das ist die MainWindow.cpp Datei meines Programms:

    #include "MainWindow.h"
    #include "ui_MainWindow.h"
    #include "utils.h"
    #include <QPushButton>
    #include <string>
    
    
    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        connect(ui->pbMid, SIGNAL(clicked()), this, SLOT(move()));
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    void MainWindow::moveButton(int direction, QPushButton qpb[], int xx, int yy){
    
        switch (direction+1) {
        case 1:
                for (int i = 0;i <= 100;i++){
                    yy --;
                    qpb[direction].setGeometry(xx, yy, 50, 50);
                    this->repaint();
                    ut::sleep(1);
                }
                break;
        case 2:
            for (int i = 0;i >= 100;i++){
                xx ++;
                yy --;
    //!!!!!!!!!!!!!!!!!Hier liegt der Fehler!!!!!!!
                qpb[direction].setGeometry(xx, yy, 50, 50);
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                this->repaint();
                ut::sleep(1);
            }
            qpb[direction].move (xx+100, yy);
            break;
        case 3:
            for (int i = 0;i <= 100;i++){
                xx ++;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        case 4:
            for (int i = 0;i <= 100;i++){
                xx ++;
                yy ++;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        case 5:
            for (int i = 0;i <= 100;i++){
                yy ++;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        case 6:
            for (int i = 0;i <= 100;i++){
                xx --;
                yy ++;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        case 7:
            for (int i = 0;i <= 100;i++){
                xx --;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        case 8:
            for (int i = 0;i <= 100;i++){
                xx --;
                yy --;
                qpb[direction].setGeometry(xx, yy, 50, 50);
                this->repaint();
                ut::sleep(1);
            }
            break;
        }
    
    
    }
    void MainWindow::move(){
        int xStart = ui->pbMid->x();
        int yStart = ui->pbMid->y();
        QPushButton *b[8];
        for (int i = 0;i<2;i++){
            b[i] = new QPushButton(this);
            b[i]->setText(std::to_string(i).c_str());
            b[i]->setGeometry(xStart+20*i, yStart, 50, 50);
            b[i]->setVisible(true);
            moveButton(i, *b, xStart, yStart);
        }
    
    
    }
    
    

    Das Programm bricht bei der markierten Zeile ab.. alle folgenden Durchläufe sind auch nicht funktionsfähig. Der erste, vorherige Durchlauf ist erfolgreich.
    Ich habe schon probiert:
    -Andere Initialisierung und Implementierung der Positionsvariablen xx und yy

    • Nutzung von Pointern
    • Nutzung von move() statt setGeometry()
    • Definition aller Button einzeln (kein Array)
    • try und catch

    Hoffentlich hat irgendwer einen Vorschlag was das Problem ist.. danke für eure Hilfe.



  • @Schnick
    Die Zeile wird nie erreicht, das Programm bricht dort also nicht ab.

    Qt4? Warum?



  • @Schnick
    void MainWindow::moveButton(int direction, QPushButton qpb[], int xx, int yy){ die Funktion erwartet ein Array von Buttons.

    moveButton(i, *b, xStart, yStart); der Aufruf passt nicht dazu. Du übergibst einen Zeiger auf einen Button.



  • @manni66 danke, wird eigentlich schon erreicht, habs nur zu Testzwecken mal geändert gehabt und vor dem kopieren nicht Rückgängig gemacht 😅
    hab ausgetestet was bei den Nachfolgern passiert..

    Hab Qt seit langem wieder zu nutzen begonnen, wollte mich vor irgendwelchen Updates erst mal wieder etwas darin orientieren.



  • @manni66 Ich übergebe *b, was als Pointer bereits initialisiert wurde... sollte daher nur das normale Array übergeben... schaue mir das nochmal an, sollte aber eigentlich zwar nicht so sinnvoll sein, jedoch funktionieren...

    Danke für deine Hilfe ✌🏼



  • @Schnick

    sollte aber eigentlich zwar nicht so sinnvoll sein, jedoch funktionieren...

    Nein!



  • Mach es dir doch einfacher: Erzeuge von vorn herein 9 Buttons und ändere nur die Sichtbarkeit der 8 anderen Buttons. Falls dein Ziel das hergibt.



  • Ich würde sagen:

    Die moveButton-Funktion soll einen Button verschieben in Abhängigkeit der Richtung. Die Parameter von moveButton sollten daher sein: genau ein (Pointer auf) Button, die Richtung und die Entfernung (die 100 in deinem Code).

    Bislang nimmt die moveButton-Funktion die Richtung, ein Array von Buttons, x und y. Vor allem benutzt du die Richtung, um in das qbp-Array zu indexieren. Das erscheint völlig wirr. Die moveButton-Funktion braucht doch gar nicht zu wissen, wie viele Buttons es gibt. xx, yy und die width und height könnte man direkt aus dem existierenden Button ermitteln.

    Außerdem hast du in dem switch/case praktisch identischen Code - und einmal hat die for-Schleife die falsche Abbruchbedingung. Du könntest in dem switch einfach nur ein deltaX/deltaY berechnen und ansonsten dieselbe Schleife für alle Richtungen verwenden. Oder - und weil "int" für eine Richtung falsch und unflexibel erscheint, könntest du die deltaX und deltaY (vielleicht sogar als float) als Paramter einführen und stattdessen den direction-Parameter entfernen.