QTableView和horizo​​ntalHeader() - > restoreState()

时间:2009-07-22 04:13:01

标签: qt qtableview

我无法缩小这个bug,然而我似乎遇到了以下问题:

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

我知道,这不是很具描述性,但我希望其他人之前有这个问题。

5 个答案:

答案 0 :(得分:2)

对于QMainWindow,save/restoreState采用版本号。 QTableView's restoreState()没有,所以你需要自己管理这个案例。

如果要恢复状态,即使模型不匹配,也可以选择以下选项:

  • 在保存时将状态与模型中存在的列列表一起存储,这样如果列不匹配,则可以避免从数据中恢复,并恢复为defualt case
  • 实现您自己的处理该案例的保存/恢复状态函数(ugh)
  • 添加一个代理模型,该代理模型为正在恢复的状态提供虚假/虚拟列,然后在之后删除这些列。

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

以下是我使用Boost Serialization制作的解决方案。

它或多或少地处理新列和删除列。适用于我的用例。

  // 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
  };

答案 3 :(得分:0)

如果你改变模型,我希望它会破裂!这些函数直接保存和恢复私有类成员变量,而不进行任何健全性检查。尝试恢复状态,然后更改模型。

答案 4 :(得分:-1)

我试图在遇到同样的问题后为Qt 5.6.2解决这个问题。看到 this link for a Qt patch under review,它使restoreState()处理保存状态中的部分(例如列)数与当前视图中的部分数不匹配的情况。