QTableView and horizontalHeader () & # 8594; restoreState ()

I cannot narrow down this error, but I seem to have the following problem:

  • saveState() a horizontalHeader()
  • restart application
  • change the model so that it has less than a column
  • restoreState()
  • Now, for some reason, the state of the headerview is completely confused. I cannot show or hide any new columns, and I cannot get a reasonable state back

I know this is not very descriptive, but I hope others have had this problem before.

+3
source share
5 answers

For QMainWindow save/restoreState accepts the version number. QTableView restoreState () does not do this, so you need to manage this case yourself.

If you want to restore the state, even if the model does not match, you have the following options:

  • Save the state along with the list of columns that existed in the model when saving, so you can avoid recovering from the data if the columns do not match, and return to defualt case
  • Implement your own save / restoreState functions that handle this case (ugh)
  • Add a proxy model that provides dummy / dummy columns for the state that is being restored, and then deletes these columns immediately.
+2
source

I personally never use saveState() / restoreState() in any Qt widgets, as they just return a binary block. I want my configuration files to be readable, with simple types. It also eliminates such problems.

In addition, QHeaderView has the mischievous problem that restoreState() (or equivalents) only ever worked for me when the model was already installed, and then for a while. I ended up connecting to the QHeaderView::sectionCountChanged() signal and set the state in the slot called from it.

+1
source

Here is the solution I made using Boost Serialization.

It handles new and deleted columns, more or less. Works for my use cases.

  // Because QHeaderView sucks struct QHeaderViewState { explicit QHeaderViewState(ssci::CustomTreeView const & view): m_headers(view.header()->count()) { QHeaderView const & headers(*view.header()); // Stored in *visual index* order for(int vi = 0; vi < headers.count();++vi) { int li = headers.logicalIndex(vi); HeaderState & header = m_headers[vi]; header.hidden = headers.isSectionHidden(li); header.size = headers.sectionSize(li); header.logical_index = li; header.visual_index = vi; header.name = view.model()->headerData(li,Qt::Horizontal).toString(); header.view = &view; } m_sort_indicator_shown = headers.isSortIndicatorShown(); if(m_sort_indicator_shown) { m_sort_indicator_section = headers.sortIndicatorSection(); m_sort_order = headers.sortIndicatorOrder(); } } QHeaderViewState(){} template<typename Archive> void serialize(Archive & ar, unsigned int) { ar & m_headers; ar & m_sort_indicator_shown; if(m_sort_indicator_shown) { ar & m_sort_indicator_section; ar & m_sort_order; } } void restoreState(ssci::CustomTreeView & view) const { QHeaderView & headers(*view.header()); const int max_columns = std::min(headers.count(), static_cast<int>(m_headers.size())); std::vector<HeaderState> header_state(m_headers); std::map<QString,HeaderState *> map; for(std::size_t ii = 0; ii < header_state.size(); ++ii) map[header_state[ii].name] = &header_state[ii]; // First set all sections to be hidden and update logical // indexes for(int li = 0; li < headers.count(); ++li) { headers.setSectionHidden(li,true); std::map<QString,HeaderState *>::iterator it = map.find(view.model()->headerData(li,Qt::Horizontal).toString()); if(it != map.end()) it->second->logical_index = li; } // Now restore for(int vi = 0; vi < max_columns; ++vi) { HeaderState const & header = header_state[vi]; const int li = header.logical_index; SSCI_ASSERT_BUG(vi == header.visual_index); headers.setSectionHidden(li,header.hidden); headers.resizeSection(li,header.size); headers.moveSection(headers.visualIndex(li),vi); } if(m_sort_indicator_shown) headers.setSortIndicator(m_sort_indicator_section, m_sort_order); } struct HeaderState { initialize<bool,false> hidden; initialize<int,0> size; initialize<int,0> logical_index; initialize<int,0> visual_index; QString name; CustomTreeView const *view; HeaderState():view(0){} template<typename Archive> void serialize(Archive & ar, unsigned int) { ar & hidden & size & logical_index & visual_index & name; } }; std::vector<HeaderState> m_headers; bool m_sort_indicator_shown; int m_sort_indicator_section; Qt::SortOrder m_sort_order; // iff m_sort_indicator_shown }; 
+1
source

I would expect it to break if you change the model! These functions automatically save and restore private class member variables without any sanity checks. Try restoring the state and then changing the model.

0
source

I am trying to fix this problem for Qt 5.6.2 after you encounter the same problem. See this link for the Qt fix under consideration , which makes restoreState () handle the case when the number of sections (for example, columns) in the saved state does not match the number of sections in the current view.

-1
source

All Articles