Search code examples
qtdialogqt-designerslot

Program crashed when calling QColorDialog into a slot function connected to a widget defined thanks to qt-designer


I designed a push button thanks to Qt-designer, named colorizeButton, and connected it to a slot in my code :

.h :

class MainWindow : public QMainWindow
{
    Q_OBJECT

private:
    Draw *  draw;

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots :
    void colorize();

private:
    Ui::MainWindow *ui;
};

.cpp, constructor of my QMainWindow :

draw = new Draw(parent);
setCentralWidget(draw);

ui->setupUi(this);
ui->colorizeButton->setAutoDefault(false);
connect(ui->colorizeButton, SIGNAL(clicked()), this, SLOT(colorize()));

.cpp, after :

void MainWindow::colorize() {
    cout << "colorize()" << endl;
    QColor color = QColorDialog::getColor(Qt::black, draw);
    draw->Draw::setColor(color);
}

When I run this and click on the colorizeButton, "colorize()" is printed out, but then the program crashes. Do you understand why ?

I am confused because, before that, I used a QAction and a similar connection (it was just "triggered()" instead of "clicked") and it worked : I could interact with the QColorDialog.

Thank you by advance ! :D


Solution

  • This line of code looks odd:

    draw->Draw::setColor(color);
    

    I suppose that Draw's base class is QWidget and you want to change color of its background. You can do it like this:

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        draw = new QWidget(); // No need to set its parent because setCentralWidget sets it
    }
    
    void MainWindow::on_btnColorize_clicked()
    {
        QColor color = QColorDialog::getColor(Qt::black, draw); // I do not know why you use draw as a parent for QColorDialog
    
        QPalette pal = palette();
        pal.setColor(QPalette::Background, color);
        draw->setAutoFillBackground(true);
        draw->setPalette(pal);
        this->setCentralWidget(draw);
    }
    

    Note that in such case draw will take the whole MainWindow.