PDA

View Full Version : QListWidget->QStackWidget->QTableView question



scott_hollen
5th March 2011, 21:34
Okay, I know I'm a babe in the woods with Qt and after a few days trying to solve this on the "Newbie" thread I thought I'd try again here...I think it comes down to something simple...

I have a list widget consisting of 5 push buttons. These are connected to a stacked widget of 5 tab widgets. On one of these tab widgets (A User admin one) is a TableView populated by a QSqlTableModel. A clicked() signal on on a button connects to a show() slot for this widget; I also have a clicked() signal connected to a slot called MainWindow::On_UserPB_Clicked. This is where I need help.

If I create my QSqlTableModel in the On_UserPB_Clicked slot and feed it to my TableView, everything works perfectly. I can add to it and edit it, I can click on other push buttons in my list widget and come back to the User tabwidget and all is well. However, according to everything I'm reading, I really should be creating the model and populating the TableView in the MainWindow::MainWindow constructor, but when I do this, my tab widget still gets displayed correctly, but there is no TableView to work with, and I don't know how to get this to appear.

Is there another signal I need to be capturing? I tried to connect a clicked() signal to a show() and an update() slot for my TableView, but to no avail...Should I quit trying to make this work and move on?

I'm saving space and not posting the code (plus it's actually working when in the slot), I just don't know how to get it to display if it's defined in the constructor...

Thanks in advance!

scott

d_stranz
5th March 2011, 23:25
I'm saving space and not posting the code (plus it's actually working when in the slot), I just don't know how to get it to display if it's defined in the constructor...

And without showing us at least that constructor code, how are we supposed to have even a clue about what you might be doing wrong?

scott_hollen
6th March 2011, 03:23
Well, in order to not waste anyone's time, I was asking a theoretical question more so than something specific to my code as I don't like asking people to code for me. I didn't think code was necessary but since it apparently is:


MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)

{
ui->setupUi(this);

//************************************************** *****
//* Retrieve data from the USER table for managing... *
//************************************************** *****
usertablemodel = new QSqlTableModel(this);

usertablemodel->setTable ("user");
usertablemodel->sort (0, Qt::AscendingOrder);

usertablemodel->setEditStrategy (QSqlTableModel::OnManualSubmit);
usertablemodel->select ();

usertablemodel->setHeaderData (0, Qt::Horizontal,
QObject::tr("Username"));
usertablemodel->setHeaderData (1, Qt::Horizontal,
QObject::tr("Password"));
usertablemodel->setHeaderData (2, Qt::Horizontal,
QObject::tr("Full Name"));
usertablemodel->setHeaderData (3, Qt::Horizontal,
QObject::tr("Status"));
usertablemodel->setHeaderData (4, Qt::Horizontal,
QObject::tr("Access Level"));
usertablemodel->setHeaderData (5, Qt::Horizontal,
QObject::tr("User Name"));
usertablemodel->setHeaderData (6, Qt::Horizontal,
QObject::tr("Activity Date"));

ui->ManageUsersTV->setModel (usertablemodel);
ui->ManageUsersTV->resizeColumnsToContents ();

ui->ManageUsersTV->setEditTriggers (QAbstractItemView::AnyKeyPressed |
QAbstractItemView::DoubleClicked);

}


I have a slot called on_AdminPB_clicked connected to a pushbutton (signal onclicked()) where the code above currently exists now, which works perfectly, but I just would prefer to have it in the constructor not the slot. I don't know what code to place in my slot in order to have the tableview display if the code is defined in the constructor vs. the slot.

d_stranz
6th March 2011, 23:29
First thing that comes to mind is that if you are creating a table model in a slot every time the slot is called, then you have a built-in memory leak. As you have surmised, it is generally more correct to create the model (and the view) in the constructor, and simply update the model (and thus the view) in response to user actions.

In my use of models, I declare them as stack-based member variables of the MainWindow: QAbstractTableModel userModel; (not * userModel). This ensures that the model gets properly deleted when the main window instance goes out of scope. In this case you call setModel( &userModel ) on the view.

It isn't clear what you mean by "there is no table view to work with". Is there no table view at all (a blank space where the table view should be?), or do you mean that the table view is visible but not populated with data?

If it is the former, then you either have the widget parenting incorrect, you have made the table invisible (in the designer maybe?), you haven't set a layout somewhere, or any nmber of things.

If it is the latter, then the table probably isn't getting updated in the main window constructor because it isn't visible yet. In my use of table views with custom models, I have noticed that the model::data() method is only called for row and column indexes that are actually visible.

As a first step, I would try moving the select() and resizeColumnsToContents() calls out of the constructor (leaving everything else there), and putting it in your push button onclicked() slot, assuming your tab widget and table are now properly visible on screen.

scott_hollen
25th March 2011, 19:41
Thanks for the reply -- I haven't been able to focus on my Qt project with some family issues going on so I apologize for not responding...

I'm not sure why right now, but if I move the model/view creation to the constructor, then click on the button linked to my slot, the screen that appears is completely blank...No tableviews, no pushbuttons, nothing. If I move the exact code back to the slot, everything appears and I could do the data entry/editing as needed...So, in short, the former....I haven't had too much of a chance to investigate...

I am worried about memory leaks but right now my father-in-law is putting me under the gun to just get *something* to his client that we can tweak later...That's grating to me because he's asking to make other shortcuts that I don't like (raw text data entry when I prefer comboboxes linked to lookup tables, for example). It's a fairly small project (for experts -- for newbies like me with a full time job, huge) so memory leaks probably won't have much of an impact, but they're still worrisome...

Thanks for the advice -- I'll troubleshoot some on this this weekend!


scott

scott_hollen
27th March 2011, 16:39
Just figured this out -- we were both wrong because I gave incomplete information and I just didn't make the connection in my brain...

When my app first starts, the user is presented with a log in screen. This takes place in my on_LoginPB_clicked() slot, which is fired from a LOGIN pushbutton on a form that takes a username, password, and DB path...Since this is where the DB connection is created, defining my tableviews in the constructor can't work because it doesn't have a DB to operate against...

If I put the code I posted earlier in the on_LoginPB_clicked() slot -- which is only ever called once -- after a successful log in, then it all works perfectly...

As Bug Bunny puts it -- what a maroon...Sometimes it helps to just slow down and think logically about what's happening...

thanks for the help!!!


Scott