QTableView и horizontalHeader () -> restoreState () - PullRequest
3 голосов
/ 22 июля 2009

Я не могу сузить эту ошибку, однако Кажется, у меня следующая проблема:

  • saveState() из horizontalHeader()
  • перезапустить приложение
  • изменить модель так, чтобы она имела на один столбец меньше
  • restoreState()
  • Теперь по какой-то причине состояние заголовка полностью испорчено. Я не могу показать или скрыть какие-либо новые столбцы, и при этом я никогда не могу вернуть разумное состояние

Я знаю, это не очень наглядно, но я надеюсь, что у других была эта проблема раньше.

Ответы [ 5 ]

2 голосов
/ 10 декабря 2009

Для QMainWindow, save/restoreState принимает номер версии. QSableView's restoreState () нет, поэтому вам нужно самостоятельно управлять этим делом.

Если вы хотите восстановить состояние, даже если модель не соответствует, у вас есть следующие опции:

  • Сохранять состояние вместе со списком столбцов, которые существовали в модели при сохранении, поэтому вы можете избежать восстановления из данных, если столбцы не совпадают, и вернуться к регистру по умолчанию
  • Реализация собственных функций save / restoreState, которые обрабатывают этот случай (тьфу)
  • Добавьте прокси-модель, которая содержит фиктивные / фиктивные столбцы для восстанавливаемого состояния, а затем удалите эти столбцы.
1 голос
/ 04 апреля 2010

Вот решение, которое я сделал с помощью 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
  };
1 голос
/ 22 июля 2009

Лично я никогда не использую saveState() / restoreState() в любом виджете Qt, так как они все равно просто возвращают двоичный двоичный объект. Я хочу, чтобы мои файлы конфигурации были удобочитаемыми, с простыми типами. Это также избавляет от подобных проблем.

Кроме того, QHeaderView имеет непослушную проблему, которую restoreState() (или ее эквиваленты) сработали только для меня, когда модель уже была установлена, а затем некоторое время. В итоге я подключился к сигналу QHeaderView::sectionCountChanged() и установил состояние в слоте, который вызывается из него.

0 голосов
/ 30 мая 2016

Я пытаюсь исправить эту проблему для Qt 5.6.2, после того, как решаю ту же проблему. Увидеть эта ссылка для рассматриваемого патча Qt , которая заставляет restoreState () обрабатывать случай, когда количество разделов (например, столбцов) в сохраненном состоянии не совпадает с количеством разделов в текущем представлении.

0 голосов
/ 22 июля 2009

Я бы ожидал, что он сломается, если вы смените модель! Эти функции сохраняют и восстанавливают переменные-члены закрытого класса напрямую без каких-либо проверок работоспособности. Попробуйте восстановить состояние, а затем изменить модель.

...