QTreeWidget медленное удаление после клика - PullRequest
0 голосов
/ 07 декабря 2018

Я создал QTreeWidget для отображения очень большого и непрерывного набора данных.Поскольку набор данных является непрерывным, я удаляю исходные строки, когда общее количество строк превышает указанное количество.

Вся система работает правильно и отображает данные.

Но когда я нажимаюв древовидном представлении вся система замедляется.Я отладил.И проблема в коде удаления, удаление каждого QTreeWidgetItem стоит много времени после нажатия ~ 20 мс

Я отладил его в источнике Qt, и проблема, похоже, была с QItemSelectionModel :: setCurrentIndex

Эта строка -> emit currentChanged (d-> currentIndex, previous);

Теперь я не мог отлаживать его дальше, так как не мог выяснить, какие слоты подключены к этому сигналу, и замедлять его.

Я использую Qt 4.7.1

Я вставил весь код ниже:

Заголовочный файл:

    #ifndef WINDOW_H
    #define WINDOW_H

    #include <QWidget>
    #include "ui_service.h"
    #include <qtimer.h>

    typedef std::pair<std::string, std::string> tSEntry;
    typedef std::vector<tSEntry> tSFifo;

    typedef struct tGUIData
    {
       std::string strCName;

       std::string strFName;
       std::string strPName;

       std::string strMName;
       std::string strMIDHex;
       std::string strMIDDec;

       std::string strTimeStamp;

       std::string strRawDataHex;
       std::string strRawDataDec;

       tSFifo oSQueue;

    } tGUIData;



    class Window : public QWidget
    {
        Q_OBJECT

       /// The Tree Widget where the data is shown
       QTreeWidget* m_pTreeHead;
       Ui::ListView* m_pForm;
       int m_nMaxItemAmount;

       QTimer m_oDataProducer;
       QTimer m_oListClearer;
    public:
        Window();
        ~Window();
    private slots:
       void ProduceData();
       void ClearTree();
       void Window::AddEntry(tGUIData& tGUIData);

    private:
       void Window::DeleteItems();

    };

    #endif

Файл кода:

  #include <QtGui>

  #include "window.h"
  #include <cstdlib>
  #include <ctime>

  Window::Window()
  {
     m_pForm = new Ui::ListView();
     m_pForm->setupUi(this);

     QHeaderView* pHeader = m_pForm->treeWidget->header();
     pHeader->setResizeMode(0, QHeaderView::Interactive);
     pHeader->setResizeMode(1, QHeaderView::Interactive);
     pHeader->setResizeMode(2, QHeaderView::Interactive);
     pHeader->setResizeMode(3, QHeaderView::Interactive);
     pHeader->setResizeMode(4, QHeaderView::Stretch);

     m_pTreeHead = m_pForm->treeWidget;

     m_nMaxItemAmount = 1000;

     m_oDataProducer.start(1);
     m_oListClearer.start(10);
     connect(&m_oDataProducer, SIGNAL(timeout()), this, SLOT(ProduceData()));
     connect(&m_oListClearer, SIGNAL(timeout()), this, SLOT(ClearTree()));
  }


  std::string CreateRandomString(size_t nLength)
  {
     std::string o_str = "";
     o_str.resize(nLength);
     char cSymbols[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
     unsigned int nIndexer = 0;
     srand(static_cast<long int>(std::time(NULL)) + rand());
     while (nIndexer < nLength)
     {
        o_str[nIndexer++] = cSymbols[rand() % 62];
     }
     return o_str;
  }


  void Window::ClearTree()
  {
     DeleteItems();
  }

  void Window::ProduceData()
  {
     for (size_t i = 0; i < 500; i++)
     {

        tGUIData oGUIData;
        oGUIData.strCName = CreateRandomString(10);
        oGUIData.strFName = CreateRandomString(10);
        oGUIData.strMIDDec = CreateRandomString(10);
        oGUIData.strMIDHex = CreateRandomString(10);
        oGUIData.strMName = CreateRandomString(10);



        tSEntry oSEntry;
        oSEntry.first = CreateRandomString(10);
        oSEntry.second = CreateRandomString(10);
        oGUIData.oSQueue.push_back(oSEntry);

        AddEntry(oGUIData);
     }
  }

  Window::~Window()
  {
     m_oDataProducer.stop();
     if (m_pForm)
     {
        delete m_pForm;
        m_pForm = NULL;
     }
  }


  void Window::DeleteItems()
  {
     while (m_pTreeHead->topLevelItemCount() >= m_nMaxItemAmount)
     {
        QTreeWidgetItem* pTreeWidget = m_pTreeHead->topLevelItem(0);
        if (pTreeWidget)
        {
           delete pTreeWidget;
           pTreeWidget = NULL;
        }
     }
  }


  void Window::AddEntry(tGUIData& oGUIData)
  {
     QTreeWidgetItem* pMessageItem = new QTreeWidgetItem(m_pTreeHead);

     pMessageItem->setText(0, oGUIData.strCName.c_str());
     pMessageItem->setText(1, oGUIData.strMName.c_str());
     pMessageItem->setText(2, oGUIData.strTimeStamp.c_str());
     pMessageItem->setText(3, oGUIData.strRawDataDec.c_str());
     pMessageItem->setText(4, oGUIData.strPName.c_str());

     while (!oGUIData.oSQueue.empty())
     {
        QTreeWidgetItem* pSubItem = new QTreeWidgetItem(pMessageItem);
        tSEntry& sEntry = oGUIData.oSQueue.front();
        pSubItem->setText(1, sEntry.first.c_str());
        pSubItem->setText(2, sEntry.second.c_str());

        oGUIData.oSQueue.erase(oGUIData.oSQueue.begin());
     }

  }

1 Ответ

0 голосов
/ 07 декабря 2018

При удалении элементов отключите обновление, например:

QTreeWidget tw;
tw.setUpdatesEnabled(false);

Для удаления всех элементов используйте (если элементы не содержат указателей):

tw.clear()

Вы не делаетенеобходимо удалить элементы перед деструктором QTreeWidget.

...