PDA

View Full Version : Set header labels



Radek
22nd August 2013, 18:12
I have created a QTreeWidget with 4 columns using a Designer. It works but my header columns are "1 2 3 4". I tried setHeaderLabels():



Tree::Tree( QWidget *parent ) : QTreeWidget(parent)
{
QStringList labels = {"title", "author", "source", "date" };

setHeaderLabels(labels);

TreeHeader = header(); // TreeHeader is QHeaderView *

TreeHeader->setResizeMode(0,QHeaderView::Stretch);
TreeHeader->setSectionHidden(1,true);
TreeHeader->setSectionHidden(2,true);
TreeHeader->setSectionHidden(3,true);
TreeHeader->setVisible(false);
}



(At the beginning: we have no header and only one column in the view.) but I still have columns "1 2 3 4". Perhaps, because setHeaderLabels() adds columns instead of updating them according to the documentation. I have searched something what updates header labels but I have found nothing. How should I set the header labels?

wysota
22nd August 2013, 18:29
setHeaderLabels() does not add new columns. However with QTreeWidget you should set headers by accessing QTreeWidget::headerItem().

Radek
22nd August 2013, 19:01
GP fault. I updated the code:



Tree::Tree( QWidget *parent ) : QTreeWidget(parent)
{
QTreeWidgetItem *HeaderItem = headerItem();

TreeHeader = header();

HeaderItem->setText(0,"title");
HeaderItem->setText(1,"author");
HeaderItem->setText(2,"source");
HeaderItem->setText(3,"date");

setHeaderItem(HeaderItem);

TreeHeader->setResizeMode(0,QHeaderView::Stretch);
TreeHeader->setSectionHidden(1,true);
TreeHeader->setSectionHidden(2,true);
TreeHeader->setSectionHidden(3,true);
TreeHeader->setVisible(false);
}


And got a GP fault when I tried to show the header after changing view:



case 1 :
{
ui.splitter->setOrientation(Qt::Vertical); // wndTree is a QTreeWidget, wndText is a QTextEdit (descendants) in a splitter window
ui.wndTree->TreeHeader->setSectionHidden(1,false);
ui.wndTree->TreeHeader->setSectionHidden(2,false);
ui.wndTree->TreeHeader->setSectionHidden(3,false);
ui.wndTree->TreeHeader->setVisible(true); // <-- GP fault
conf.ViewType = 2;
}
break;


The debugger shows that the HeaderItem in the Tree ctor is non null. Note: with "1 2 3 4" the code works as it should. Any suggestions?

wysota
22nd August 2013, 20:19
What is this TreeHeader member of ui.wndTree? How is it related to the local TreeHeader variable you create in constructor of the Tree class?

Radek
23rd August 2013, 06:23
The ui.wndTree is an instance of Tree. I have created a splitter layout in the Designer, put a QTreeWidget and a QTextEdit into it and promoted the QTreeWidget to Tree and QTextEdit to Text. The Tree class contains a TreeHeader pointer to QHeaderView, which should be shown in some views and not shown in others. The views are:

case 1: side by side, no header
case 2: top and bottom, header
case 3: only tree, header
case 4: only text, no header

The views are cycled by a view selector.

wysota
23rd August 2013, 07:34
In the constructor of Tree you are not initializing the TreeHeader member variable but rather you create a new local variable that shadows the member.

Radek
23rd August 2013, 09:11
No, I am not. header() returns the pointer to the tree header which I store in the variable TreeHeader. It is the pointer to the actual header because my updating (expand first column, hide next three ones) is reflected by the header. The problem consists in my bad understanding headerItem().

According to the documentation, on setHeaderItem(), the header takes ownership of the supplied pointer and it (should) use texts in the supplied QTreeWidgetItem for the header columns. But what happens to the original headerItem()? A possible scenario: the original QTreeWidgetItem is deleted and the supplied one is set. Because I supply the pointer returned by headerItem(), an invalid pointer is set and a GP fault follows on the first use of the pointer. The pointer is first used on setVisible().
e
Well, but what to do then?

(1) Do not call setHeaderItem(): columns "1 2 3 4", the app will not crash.
(2) Create a new QTreeWidgetItem instead of updating headerItem(), set texts, call setHeaderItem(): columns "1 2 3 4", the app will not crash. In the other words, setting texts does not suffice.

wysota
23rd August 2013, 09:16
Well, but what to do then?
Your basic problem is that you call setHeaderItem() with the already set header item. You don't have to do that, just modify the item itself -- it is not a copy but the actual header item that you are modifying.


#include <QtWidgets>

int main(int argc, char **argv) {
QApplication app(argc, argv);
QTreeWidget w;
w.headerItem()->setText(0, "col0");
w.headerItem()->setText(1, "col1");
w.show();
w.addTopLevelItem(new QTreeWidgetItem());
return app.exec();
}

Radek
23rd August 2013, 10:08
This is "method 1" from the above. It does not work:



Tree::Tree( QWidget *parent ) : QTreeWidget(parent)
{
TreeHeader = header();

headerItem()->setText(0,"title");
headerItem()->setText(1,"author");
headerItem()->setText(2,"source");
headerItem()->setText(3,"date");

TreeHeader->setResizeMode(0,QHeaderView::Stretch);
TreeHeader->setSectionHidden(1,true);
TreeHeader->setSectionHidden(2,true);
TreeHeader->setSectionHidden(3,true);
TreeHeader->setVisible(false);
}


columns "1 2 3 4".

wysota
23rd August 2013, 10:14
Apparently you are doing something later on which modifies the labels. The code above hides the header whatsoever so if you see the header then somewhere else you have some code that shows it. Run my example and see that it works. The problem is elsewhere in your code.

Radek
23rd August 2013, 15:18
No success, wysota, at least, no success in Debian KDE. I commented out everything concerning the tree header from everywhere and left only headerItem()->setText() statements in the ctor. Then I made the header visible in the .ui file. Try. Columns "1 2 3 4". But I found out how to set the header texts in the Designer: Make the header visible, double click it and select "edit items". Overwrite "1 2 3 4", you can hide the header again. Recompile, try. It works :)

In the .ui file, I got the sections in the wndTree description:


<column>
<property name="text">
<string notr="true">title</string>
</property>
</column>


for each header string. A little surprise is, that there is nowhere specified which column. This seems to be done only by position in the .ui file.

Problem solved for now but a question remains open: How to set column headers on fly? For example, from some configuration file?

wysota
23rd August 2013, 15:36
No success, wysota, at least, no success in Debian KDE.
Did you run my example? Did it fail?