Program crash when button clicked



  • Hello,
    I am having some troubles trying to code a minesweeper game.

    I want to create a table of specific QPushButton (that can react to both right and let clicks) but my program crashes when i click on one of these buttons.

    Also, I don't know how to create a slot that takes an int as a input so I don't need do do :

              void onRightClicked(int num_bouton);
              void onLeftClicked(int num_bouton);
              void onRightClicked0();
              void onLeftClicked0();
    

    My code :

    dialog.cpp

        <code>#include "dialog.h"
        #include "ui_dialog.h"
        #include <QDebug>
        #include <QLayout>
        #include <QHash>
        #include <QVector>
    
        #include "mon_bouton.h"
    
    
        void Dialog::onRightClicked(int num_bouton)
        {
            qDebug() << "User right clicked me";
     //The program dies then I want to change the "case_bouton[]" here
    //but I can do it where I create the buttons
      case_bouton[num_bouton]->setText("X");
    
        }
    
        void Dialog::onLeftClicked(int num_bouton)
        {
            qDebug() << "User left clicked me";
            case_bouton[num_bouton]->setText("clic gauche");
        }
    
        void Dialog::onRightClicked0()
        {onRightClicked(0);}
    
        void Dialog::onLeftClicked0()
        {onLeftClicked(0);}
    
        Dialog::Dialog(QWidget *parent) :
            QDialog(parent),
            ui(new Ui::Dialog)
        {
            ui->setupUi(this);
    
    QVector<mon_bouton*> case_bouton(100);
    for(int j=0; j < 10; j++)
        {
        for(int i = 0; i < 10; i++)
            {
           case_bouton[i+j*10] = new mon_bouton(this);
           case_bouton[i+j*10]->setGeometry(10+36*j,10+i*36, 35,35);
            }
        }
    
        connect(case_bouton[0], SIGNAL(clicked()), this, SLOT(onLeftClicked0()));
    
        //connect(case_bouton[0], SIGNAL(clic_droit()), this, SLOT(onRightClicked()));
    
        }
    
        Dialog::~Dialog()
        {
            delete ui;
    
    
        }
    

    dialog.h

            #ifndef DIALOG_H
       #define DIALOG_H
    
       #include <QDialog>
       #include "mon_bouton.h"
    
       namespace Ui {
       class Dialog;
       }
    
       class Dialog : public QDialog
       {
           Q_OBJECT
    
       public:
           explicit Dialog(QWidget *parent = 0);
           ~Dialog();
    
       public slots:
           void onRightClicked(int num_bouton);
           void onLeftClicked(int num_bouton);
           void onRightClicked0();
           void onLeftClicked0();
    
       private:
           Ui::Dialog *ui;
    
       protected :
           QMap <int,  mon_bouton*> case_bouton; //une collection de pointeurs
       };
       
       #endif // DIALOG_H
    

    mon_bouton.h

       #ifndef MON_BOUTON_H
       #define MON_BOUTON_H
    
       #include <QPushButton>
       #include <QMouseEvent>
    
       class mon_bouton :public QPushButton
       {
           Q_OBJECT
    
       public:
           explicit mon_bouton(QWidget *parent = 0);
    
       public slots:
           void mousePressEvent(QMouseEvent *e);
    
       signals:
           void clic_droit();
           void clicked();
    
       };
    
       #endif // MON_BOUTON_H
    

    mon_bouton.cpp

       #include "mon_bouton.h"
    
       mon_bouton::mon_bouton(QWidget *parent):
           QPushButton(parent)
       {
       }
    
       void mon_bouton::mousePressEvent(QMouseEvent *e)
       {
           if(e->button()==Qt::RightButton)
               emit clic_droit();
    
           if(e->button()==Qt::LeftButton)
               emit clicked();
       }
    

    Thank you for your help, Matuvu


  • Lifetime Qt Champion

    Hi,

    case_bouton is empty. You have a QMap of that name as member variable and a QVector with the same name in your constructor. You are filling the vector not the map.

    Also, you should take a look at QSignalMapper, that can simplify your code a bit.



  • Hi SGaist,
    Thank you very much, I was quitte lost between QMap and QVector.

    Now, I am looking how to use the QSignalMapper function that seems to be what I need but I don't really understand Qt documentation's. Do you know any tutorial on how to use it?

    EDIT :

    I've tried for hour to use QSignalMapper with no results.
    Is it possible to do some thing like that :

    void Dialog::onRightClicked(int num_bouton)
    {
        qDebug() << "User right clicked me";
         case_bouton[num_bouton]->setText("X");}
    

    ??

    Otherwise I don't see how I am supposed to link each clicked() signal from each button to the right slot (100 buttons would mean 100 slots...)

    Thank's again


  • Lifetime Qt Champion

    for(int j=0; j < 10; j++) {
        for(int i = 0; i < 10; i++) {
            mon_bouton * bouton = new mon_bouton(this);
            bouton->setGeometry(10+36*j,10+i*36, 35,35);
            case_bouton[i+j*10] = bouton;
            connect(bouton, SIGNAL(clicked()), signalMapper, SLOT(map()));
            signalMapper->setMapping(bouton, i);
         }
    }
    
    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(onClicked(int));
    


  • Thanks a lot, I had some trouble with the part :

    @SGaist said:

    signalMapper->setMapping(bouton, i);


  • Qt Champions 2016

    @Matuvu said:
    Hi what kind of problem ?

    signalMapper->setMapping(bouton, i); says:
    for this bouton, send this index (i) when clicked.
    So first bouton will send 0 when clicked and next will send 1 and so on.


Log in to reply
 

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