3

我无法缩小这个错误的范围,但是我似乎有以下问题:

  • saveState()一个horizontalHeader()
  • 重启应用
  • 修改模型,使其少一列
  • restoreState()
  • 现在,由于某种原因,headerview 的状态完全搞砸了。我无法显示或隐藏任何新列,也无法恢复合理的状态

我知道,这不是很有描述性,但我希望其他人以前也遇到过这个问题。

4

5 回答 5

2

对于 QMainWindow,save/restoreState需要一个版本号。QTableView 的 restoreState() 没有,所以你需要自己管理这种情况。

如果即使模型不匹配也想恢复状态,您有以下选项:

  • 在保存时将状态与模型中存在的列列表一起存储,因此如果列不匹配,您可以避免从数据中恢复,并恢复为默认大小写
  • 实现您自己的保存/恢复状态函数来处理这种情况(呃)
  • 添加一个代理模型,该模型为正在恢复的状态提供虚假/虚拟列,然后删除这些列。
于 2009-12-10T15:05:47.427 回答
1

Here is the solution I made using Boost Serialization.

It handles new and removed 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
  };
于 2010-04-03T22:39:45.947 回答
1

我个人从不在任何 Qt 小部件中使用saveState()/ restoreState(),因为它们只是返回一个二进制 blob。我希望我的配置文件是人类可读的,具有简单的类型。这也摆脱了这些问题。

此外,QHeaderView有一个顽皮的问题restoreState()(或等价物)只有在模型已经设置好时才对我有用,然后是一段时间。我最终连接到QHeaderView::sectionCountChanged()信号并在从中调用的插槽中设置状态。

于 2009-07-22T04:49:41.780 回答
0

如果您更改模型,我希望它会损坏!这些函数直接保存和恢复私有类成员变量,无需任何健全性检查。尝试恢复状态,然后更改模型。

于 2009-07-22T04:23:14.970 回答
-1

在遇到同样的问题后,我正在尝试为 Qt 5.6.2 解决这个问题。请参阅 此链接以了解正在审查的 Qt 补丁,它使 restoreState() 处理保存状态中的节数(例如列)与当前视图中的节数不匹配的情况。

于 2016-05-29T21:00:00.580 回答