Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Button click fails



  • I didn't know how to title this any other way.

    I have a TableWidget, three buttons and SQLite3.

    ss-1.png

    When I click Add, I get this:

    ss-add-2.png

    And if I click Cancel, I get this:

    ss-1.png

    This is expected. But, if I click Add and enter some text:

    ss-3.png

    and then click Cancel, I get this:

    ss-4.png

    The code for the two Click Events is:

    void MainWindow::on_pushButton_AddCustomer_clicked()
    {
        QSqlQuery q(swDB);
        if (!swDB.open())
        {
            ui->statusBar->showMessage(swDB.lastError().text());
        } else {
            addMode = true;
            QSqlQuery q(swDB);
            q.prepare("INSERT INTO customers(cust_name) VALUES('')");
            if(!q.exec()) qDebug() << q.lastError().text();
        }
        swDB.close();
        addCustomerButtonsOff();
        ui->tableWidget_AddCustomers->setFocus();
    }
    
    void MainWindow::on_pushButton_CancelCustomer_clicked()
    {
        qDebug() << "In Cancel";
        addMode = false;
        QSqlQuery q(swDB);
        if (!swDB.open())
        {
            ui->statusBar->showMessage(swDB.lastError().text());
        } else {
            q.prepare("DELETE FROM customers WHERE cust_id = "
                      "(SELECT MAX(cust_id) FROM customers)");
            if(!q.exec()) qDebug() << q.lastError().text();
        }
        swDB.close();
        addCustomerButtonsOn();
    }
    

    Note the qDebug() statement. The only time I see that is when I click Add and then Cancel with no text in the field on the TableWidget. If I have text there and click Cancel, on_pushButton_CancelCustomer_clicked() never fires.

    So my questions are: What's keeping it from firing? And how can I work around that?

    I also have this code:

    void MainWindow::on_tableWidget_AddCustomers_cellChanged(int row, int column)
    {
        if(loading) return;
    
        QSqlQuery q(swDB);
        if (!swDB.open()) {
            ui->statusBar->showMessage(swDB.lastError().text());
        } else {
            q.prepare("UPDATE customers SET cust_name = :n WHERE cust_id = :id");
            q.bindValue(":n", ui->tableWidget_AddCustomers->item(row, 1)->text());
            q.bindValue(":id", ui->tableWidget_AddCustomers->item(row, 0)->text().toInt());
            if(!q.exec()) qDebug() << q.lastError().text();
        }
        swDB.close();
        addCustomerButtonsOn();
    }
    

    Is it because I have characters in the field when I click Cancel that this fires? I think it might be. Because when I enter some chars and then delete them and have a blank field again, I can hit Cancel and it gets canceled. Ol' Driftwood thinks he needs to rethink this one :D


  • Lifetime Qt Champion

    What underlying model do you use? You should take a look at QSqlQueryModel.



  • @Driftwood
    You are claiming that you have a button, with a slot attached to its clicked, which is outside of your table widget. You are saying that what you do inside the table widget affects whether the slot is called. I find this "unlikely". Unless, perhaps, the clicked does not get generated if you are presently in the middle of editing in the table, and is instead considered only as ending the editing; though then I wonder why it makes any different whether there is anything in the edit or not.

    Presumably your issue comes in when on_tableWidget_AddCustomers_cellChanged() --- put in a qDebug(). I imagine it fires when you change an empty cell to have some text in it, but not when you delete that text so that the cell is empty as it was before you started editing.

    What do your addCustomerButtonsOff/On() do? They don't remove/add buttons, do they...? Even if all they do is disable the Cancel button --- particularly inside on_tableWidget_AddCustomers_cellChanged() --- does that prevent the Cancel button's clicked from being called now? Comment out all the code in on_tableWidget_AddCustomers_cellChanged() --- or at least the addCustomerButtonsOn(); --- does your on_pushButton_CancelCustomer_clicked() always fire now?

    Put a fresh button outside the table, with a slot which does nothing but qDebug(). Check how that one's clicked behaves.

    This is a separate matter from @Christian-Ehrlicher's advice. You presently use QSqlQuery against one SQLite table. Consider changing that to QSqlQueryModel or QSqlTableModel, and change your QTableWidget --- which has its own internal database not bound to your data --- over to a QTableView which is bound to the SQL query/table model. You should get a better experience of keeping everything up-to-date, with less code & copying around. QSqlTableModel can even allowing editing your rows and it will do the INSERT/DELETEs for you, if you let it.



  • @JonB said in Button click fails:

    Consider changing that to QSqlQueryModel or QSqlTableModel

    I'll check that out and see what it offers.

    We were right about on_tableWidget_AddCustomers_cellChanged firing if characters are left in the field when hitting the Cancel button.

    Your answer was thorough (much appreciated, that) and I'll go over all you provided me. I've barely scratched the surface of Qt and I know that. I'm coming from Object Pascal (I used Lazarus), where the database components are data-aware and easy to work with. This is just a little different. I think, in the long run, I'll have more (and better) control over my databases with Qt. And when you throw in this excellent community, man, that's just peanut butter icing on a fat chocolate cake :D

    @Christian-Ehrlicher - Thank you for your assistance.


Log in to reply