Qt World Summit: Submit your Presentation

QTableWidget not responding / displaying properly

  • To start off, this may very well be a newbie mistake, since I just started using Qt a few days ago (I am fairly familiar with C though). I read the QTableWidget's and ~View's documentation and I also tried searching this forum and Google, to no avail.

    With that said, my problem is:
    I have a very basic Qt Widgets Application that has an empty QTableWidget, into which the user can enter information using a button that brings up a new window with input forms. (3 QString and 1 int variable.)

    I've done this by adding a new Qt Designer Form Class to the project (.h .cpp and .ui) that handles this second window, and calls a function I made in the main window's class, the function call's parameters being the user's input.
    The mentioned function looks like this:

    @void MainWindow::Writeto_Table(QString _name, long int _amount, QString _type, QString _location, int _row)@

    The collection of the user's input and the function itself is working fine, I could test that by using a passed variable in a messagebox, like this:

    @QMessageBox::information(this, "test", QString(_name));@

    So the function passes the needed variables properly, the problem probably lies in adding it to the QTableWidget.
    However, I tried using the exact same method [QTableWidget.setItem()] in a new project, and there it worked fine.
    In this project, whatever commands I give (including setting row or column number, color, adding items) nothing happens to the QTableWidget, it remains blank.

    I am pasting the whole code part that I suspect the bug is in, so this is a function in mainwindow.cpp:

    @void MainWindow::Writeto_Table(QString _name, long int _amount, QString _type, QString _location, int _row)
    ui->money_table->setHorizontalHeaderLabels(QString("HEADER 1;HEADER 2;HEADER 3;HEADER 4").split(";"));
    ui->money_table->setItem(_row, 0, new QTableWidgetItem(_name));
    ui->money_table->setItem(_row, 1, new QTableWidgetItem(_amount));
    ui->money_table->setItem(_row, 2, new QTableWidgetItem(_type));
    ui->money_table->setItem(_row, 3, new QTableWidgetItem(_location));

    QMessageBox::information(this, "test", QString(_name));


    money_table is the objectName of my QTableWidget.
    Editing the row and column numbers does nothing, the widget remains blank. If I set some before running, they stay the same (and not become 2 & 4).
    The output tests at the bottom were my struggle to get the code to do anything.
    Nothing works (the LCD display and the Label don't change) only the MessageBox.

    The fact that I am getting no errors leads me to believe that either I'm doing something fundamentally wrong or missing an important function maybe.

    After digging around for a few hours, I thought maybe I was missing this:

    @QTableWidget *money_table = new QTableWidget();
    //same things as above

    But with this, the program didn't recognize that I had a MainWindow::money_table, only if I created it in the Creator.

    Seemed odd to me, that I could not create a new TableWidget like it says in the documentation:
    @tableWidget = new QTableWidget(this);

    I had to make "tableWidget" a pointer. I suspect this is where I missed something (maybe I made a new copy of the widget, then tried manipulating that?) but I'm not used to OO-programming or Qt enough yet to spot my mistake.

    Any help would be greatly appreciated, as I am stuck on this matter and I could not find a similar problem on any Qt forum at the moment.

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Going reverse, tableWidget is never shown nor put in a layout manager thus you won't see it.

    @QTableWidget *money_table = new QTableWidget();@
    just creates a QTableWidget, again you don't show it nor put it in a layout manager so it stays invisible.

    should be called in the constructor

    Are you overwriting the content of the table widget or adding to it ?

    How are you calling Writeto_Table ?

  • Thanks for your fast reply,

    The TableWidget is intended to be totally blank at the program's first run, filled up with data from the user and then saving that data to a file later on (and loading it back, but that part can honestly wait).
    So, I am adding content to the table.

    I am calling the Writeto_Table(..) in the second window's class, like this:
    @void second_window::on_btn_Add_clicked()

    QString name = ui->add_name->text();
    long int amount = ui->add_amount->value();
    QString type = ui->add_type->currentText();
    QString location = ui->add_location->currentText();
    MainWindow obj;
    obj.Writeto_Table(name, amount, type, location, row);


    //I declared int row already, and the location & type come from ComboBoxes, hence the currentText function.
    This part of the code seems to be working well as the data gets passed into the MainWindow class, just not onto the Table.

    Coming from Visual Studio, I may have some false preconceptions.
    So, if I:

    Create an object with the Creator or in the code (this should be the same)

    Access that object in the code, like setItem()

    Expect the data I passed to the object to appear on screen

    Am I

    • fundamentally wrong? (I need to create the widget in code, then set all properties, data, and then make it visible)
    • missing a command to make my changes to the Table visible? (I tried show() above, but the Widget is already visible, although it is blank)
    • as you wrote, put it in the layout manager? (- though reading the docs, this seems to only manipulate the alignments of the widgets. I have no problems with that part.)

    I can upload some screenshots of the program, though there is not much to see other than an empty table and a MessageBox displaying the correct string that was given by the user. It's also not in English (I quickly translated variable names here for quicker explanation).


  • Lifetime Qt Champion

    Ok, one problem you have is that you are calling Writeto_Table on a local instance of MainWindow that will be destroyed at the end of on_btn_Add_clicked.

    If I've followed you correctly, you should have a QMainWindow and a custom Designer based QDialog is that right ? So what is second_window ?

    As for the row management row++ won't help here, you need to increase the row count on your table widget each time you want to add a new row

  • That custom designer class (QDialog) is what I named second_window.

    I see what you're saying, the object does get destroyed at the end of the btn_clicked function, but before that it executes. The MessageBox at the end of it appears, with the correct _name variable, so why don't the lines above it run?
    I can access the ui and ui->money_table since I'm in the MainWindow class at that point.

    Thanks for the info on row management, I reworked that bit. (obviously, I can't test yet)

    I'm now trying to use signals and slots to make it work, but if there is a "standard" way of calling a widget in the main window from a secondary window in Qt, please don't hesitate to tell me :)

  • Lifetime Qt Champion

    So you have:

    --> Dialog called in second widget

    And you want to update the content of MainWindow from that dialog, right ?
    Just to be sure, is SecondWidget needed in between or could the dialog be called in MainWindow ?

  • Yes, the whole program could be in just the MainWindow, it works easily then:

    @ui->tableWidget->setItem(0,0, new QTableWidgetItem(ui->comboBox->currentText()));@
    //this works

    But why I started learning Qt was to have a better organized / slicker GUI than VS or other alternatives. Wouldn't have thought it was this nailbiting..

    Also, the program itself is a currency organizer, with a Table widget that will hold all the information and potentially grow large after a few months' use.

    I want the user (and myself) to have the ability to use the program, compare incomes to expenses etc. without showing them the "Add new entry" interface that takes space and is unnecessary until the user actually wants to do so.

    Basically, I want to be able to do what every Windows (and other OS) program does.

    Can you tell me which is the best/easiest/most standard way of accessing a widget from another class in Qt?

  • Lifetime Qt Champion

    It's a good goal, you just have to first do some drawings, the way I see it you need that dialog which is just fine. The second_window role is obscure to me right now so i'll just put it aside.

    So all in all:

    void MainWindow::onButtonClicked()
    MyDialog md;
    int result = md.exec();
    if (result == QDialog::Accepted) {
    appendToTable(md.name(), md.amount(), md.type(), md.location());

    Hope it helps

Log in to reply