LinuxQuestions.org
Review your favorite Linux distribution.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-12-2011, 06:25 PM   #1
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 678

Rep: Reputation: 105Reputation: 105
QT: run-time layout rendering and a bit more ;-)


Hi all, in the constructor of one of my widgets I perform the rendering at run-time; Some aspects here I have not grabbed yet, and documentation did not really clear this up to me so far. For the good order, I show my code here:

PHP Code:
StatAdminForm::StatAdminForm(QWidget *parent) :
    
QWidget(parent),
    
ui(new Ui::StatAdminForm)
{
    
ui->setupUi(this);

    
QLabel *headerLabel;
    
QSqlTableModel *table;
    
QTableView *view;

    
headerLabel = new QLabel(this);
    
headerLabel->setText("Stats Administration");

    
table = new QSqlTableModel;
    
table->database();
    
table->setTable("stats");
    
table->setSort(0,Qt::AscendingOrder);
    
table->select();

    
view = new QTableView(this);
    
view->setModel(table);
    
view->resizeColumnsToContents();

    
QGridLayout *lo = new QGridLayout;
    
lo->addWidget(headerLabel);
    
lo->addWidget(view);
    
this->setLayout(lo);

Things don't really look bad here, except that my tableview is stretched out over the whole width of the widget. How can I make sure the whole tablewview widget looks cut for the job? (no "empty" space and no absurd stretching of the columns)

The table referenced here has 3 columns: id, name and long_name;
I actually want to remove "id" from the view, or rather: let this be the index in the database, rather than the row-number in the view. How can I replace the verticalIndex with the data in column "id" (which is the primary key, and thus unique) in such a way that the table can still be edited? (having issues in this part)
 
Old 04-12-2011, 06:26 PM   #2
dugan
LQ Guru
 
Registered: Nov 2003
Location: Canada
Distribution: Slackware
Posts: 7,621

Rep: Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948Reputation: 2948
Why did you wrap C++ code in PHP tags? Use CODE tags instead please.

To get rid of the stretching of the columns, you can use the QTableView::resizeColumnsToContents().

Last edited by dugan; 04-12-2011 at 06:29 PM.
 
Old 04-12-2011, 06:29 PM   #3
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 678

Original Poster
Rep: Reputation: 105Reputation: 105
I like pretty colors ;-)
As you can see here, it makes code a bit more readable (at least to me):
Code:
StatAdminForm::StatAdminForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StatAdminForm)
{
    ui->setupUi(this);

    QLabel *headerLabel;
    QSqlTableModel *table;
    QTableView *view;

    headerLabel = new QLabel(this);
    headerLabel->setText("Stats Administration");

    table = new QSqlTableModel;
    table->database();
    table->setTable("stats");
    table->setSort(0,Qt::AscendingOrder);
    table->select();

    view = new QTableView(this);
    view->setModel(table);
    view->resizeColumnsToContents();

    QGridLayout *lo = new QGridLayout;
    lo->addWidget(headerLabel);
    lo->addWidget(view);
    this->setLayout(lo);
}

Last edited by Ramurd; 04-12-2011 at 06:30 PM.
 
Old 04-12-2011, 08:36 PM   #4
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
If I understand your requirements correctly then you might want to look at putting your view in a horizontal layout and then use a horizontal spacer. But you might need to invest sometime in working out how large you want the view to really be. To do that you need to look at the header of the view and then the size hints, something like:
Code:
int widgetSize = view->header()->sectionSizeHint(0)
               + view->header()->sectionSizeHint(1)
               + view->header()->sectionSizeHint(2);
You possibly don't need the first hint if you hide that field.
You may want to put that code in a overloaded refresh method of the window.

Last edited by graemef; 04-12-2011 at 08:37 PM.
 
Old 04-13-2011, 06:46 AM   #5
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 678

Original Poster
Rep: Reputation: 105Reputation: 105
I changed the code a bit; upon popular request I'll put it in code-tags, instead of php-tags (so much for pretty colors):

Code:
StatAdminForm::StatAdminForm(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::StatAdminForm)
{
    ui->setupUi(this);

    QLabel *headerLabel;
    QSqlTableModel *table;
    QTableView *view;
    QSpacerItem *spacer;

    headerLabel = new QLabel(this);
    headerLabel->setText("Stats Administration");

    table = new QSqlTableModel;
    table->database();
    table->setTable("stats");
    table->setSort(0,Qt::AscendingOrder);
    table->select();

    /* below 2 lines are my attempt to get column 0 as the vertical index;
     * doesn't work: when removing column 0, updates in the table are not sent
     * to the database due to this error:
     *    QSqlQuery::value: not positioned on a valid record
     */
    //table->headerData(0,Qt::Vertical,Qt::DisplayPropertyRole);
    //table->removeColumn(0);

    view = new QTableView(this);
    view->setModel(table);
    view->resizeRowsToContents();
    view->resizeColumnsToContents();

    /* calculating the size of hint this way does not seem to have any effect */
    //int hint = view->horizontalHeader()->sectionSizeHint(0) +
    //        view->horizontalHeader()->sectionSizeHint(1) +
    //        view->horizontalHeader()->sectionSizeHint(2);

    int hint = view->columnWidth(0) + view->columnWidth(1) + view->columnWidth(2);
    qDebug() << "hint =" << hint;
    view->setMinimumWidth(hint);
    view->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);

    QVBoxLayout *vlo = new QVBoxLayout;

    vlo->addWidget(headerLabel);
    vlo->addWidget(view);
    vlo->setAlignment(headerLabel,Qt::AlignCenter);
    vlo->setAlignmnet(view,Qt::AlignLeft);

    this->setLayout(vlo);
    this->repaint();
}
The outcome is getting closer: the TableView is shown in full length (what I wanted), but does not have enough width this time (whereas it expanded to the entire width of the widget earlier - which was too much), while there is plenty of space to the right of the widget, so it must have space to expand, which it doesn't for some reason. QGridLayout does not seem to allow spacers (insertItem() only accepts a LayoutItem and a spacer is not a widget. I guess I'm using the wrong style of Layout here, but my attempts so far have not yet borne fruit; A spacer does not seem logical here at this point, unless it is to prevent the widget to take too much space; but right now nothing I do seems to expand the thing anymore...
 
Old 04-13-2011, 08:30 AM   #6
graemef
Senior Member
 
Registered: Nov 2005
Location: Hanoi
Distribution: Fedora 13, Ubuntu 10.04
Posts: 2,379

Rep: Reputation: 148Reputation: 148
You probably need to move the widget resize out of the constructor into a different method which you attach to via the geometriesChanged() signal.

If so, the reasoning would be that the view is not populated during the constructor and so the sizehints don't yield meaningful values.

Here is an example of something I have done
Code:
void StatWordCount::refresh()
{
   ui->treeStatsChapter->header()->setResizeMode(1,QHeaderView::ResizeToContents);
   ui->treeStatsChapter->header()->setResizeMode(2,QHeaderView::ResizeToContents);
   int newSize = ui->treeStatsChapter->header()->size().rwidth()
               - ui->treeStatsChapter->header()->sectionSizeHint(1)
               - ui->treeStatsChapter->header()->sectionSizeHint(2)
               ;
   ui->treeStatsChapter->header()->resizeSection(0,newSize);
   ui->treeStatsChapter->viewport()->update();
}
Not exactly what you want, it resizes the first column to use up all remaining space. The constructor had the following connections:
Code:
    connect (ui->treeStatsChapter->header(), SIGNAL(geometriesChanged()),this,SLOT(refresh()));
    connect (ui->treeStatsChapter->header(), SIGNAL(sectionResized(int, int, int)),this,SLOT(refresh()));
 
Old 04-13-2011, 09:06 AM   #7
Ramurd
Member
 
Registered: Mar 2009
Location: Rotterdam, the Netherlands
Distribution: Slackwarelinux
Posts: 678

Original Poster
Rep: Reputation: 105Reputation: 105
interesting, will fiddle around with that;

In the mean time I have been trying and thinking more, and I think I got an error in my thinking:

The width of the widget is more than the size of the columns:
The widget has 2 borders on the side (duh), each taking a width of 1, hence:
int num_borders = 2;
The widget is filled with 3 columns, each has a border to the left and to the right, but sharing one if one is already there
The maths on that would make num_columns + 1 = amount of column-borders (each with a width of 1)
int num_columns = 3; // gives 4 borders |1|2|3| + num_borders for the widget

The vertical header also takes space; So I get to this calculation, and this seems to fit perfectly:
Code:
    hint = view->columnWidth(0) 
         + view->columnWidth(1) 
         + view->columnWidth(2) 
         + view->verticalHeader()->width() 
         + (num_columns + 1) 
         + num_borders;
Then I can set the width like this:
Code:
    view->setMinimumWidth(hint);
    view->setMaximumWidth(hint);
    view->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
So, sizing the widget to fit perfectly, although it takes way more code than I had expected, actually does work. Now to set the verticalHeader data to the "id" column so I can hide that one from the view (since I don't want people to enter / alter data on that field, whereas I don't mind about the other columns, in fact: it's there to alter the other columns.)
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem rendering LQ in Firefox 3.6.10 on Win7 64-bit pljvaldez LQ Suggestions & Feedback 10 09-22-2010 12:47 PM
LXer: How to Run 32-bit Apps in 64-bit Linux LXer Syndicated Linux News 0 08-11-2009 09:50 AM
how to run 32 bit apps on 64 bit red hat 5 unix1adm Red Hat 20 08-11-2009 01:22 AM
How can I get hardware AND software OpenGL rendering at the same time? robjoski Linux - Software 2 04-01-2009 10:08 PM
Game in 96kB using real-time rendering SkyEye Linux - Games 0 05-13-2006 06:38 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration