Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [QT6][C++] Deleting item from Custom ListWidgetItem corrupting other entry in QT
Forum Updated to NodeBB v4.3 + New Features

[QT6][C++] Deleting item from Custom ListWidgetItem corrupting other entry in QT

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 314 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Krpadia123
    wrote on last edited by
    #1

    I am working on application, In which QDialog will be populated with some Custom ListWidgetItem labeled from 1 to 5, now in application requirement is that some other thread will delete the Items from dialog.

    Problem:
    As soon as first Item is deleted, it will corrupt the next item. (I can see blank item in dialog)
    ![alt text](1629eeee-ec24-4b69-80c1-322f68c43433-Screenshot (107).png image url)

    Note : Using Custom ListWidgetItem is important to make it scalable later.

    Code:

    1. mainwindow.h
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    #include <QtWidgets/QDialog>
    #include <QtWidgets/QListWidget>
    #include <QLabel>
    
    
    QT_BEGIN_NAMESPACE
    namespace Ui { class MainWindow; }
    QT_END_NAMESPACE
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        MainWindow(QWidget *parent = nullptr);
        ~MainWindow();
    
    private:
        Ui::MainWindow *ui;
    };
    #endif // MAINWINDOW_H
    
    
    //Custom WidgetItem
    class UploadJobListDialog : public QDialog
    {
        Q_OBJECT
    public:
        explicit UploadJobListDialog(std::vector<std::string> jobNames, QWidget* parent = NULL);
        void removeit(size_t i);
    
    
    private:
        void addListWidgetItems();
        QListWidget* m_pListWidget = nullptr;
    
        std::vector<std::string> m_pJobNames = {};
    
    };
    
    class QCustomListWidgetItem : public QWidget
    {
        Q_OBJECT
        public:
            explicit QCustomListWidgetItem(std::string labelText, QWidget* parent = NULL);
    
        private:
    
            QLabel* m_pItemLabel = nullptr;
            std::string m_pJobName;
    };
    
    
    1. main.cpp
    #include "mainwindow.h"
    #include <QApplication>
    #include <QHBoxLayout>
    #include <thread>
    #include <unistd.h>
    #include <mutex>
    
    std::mutex a;
    
    QCustomListWidgetItem::QCustomListWidgetItem(std::string labelText, QWidget* parent)
    : QWidget(parent), m_pJobName(labelText)
    {
        m_pItemLabel = new QLabel(QString::fromStdString(m_pJobName), this);
    }
    
    
    
    UploadJobListDialog::UploadJobListDialog(std::vector<std::string> jobNames, QWidget* parent)
        : QDialog(parent) , m_pJobNames(jobNames)
    {
        addListWidgetItems();
    }
    
    void UploadJobListDialog::addListWidgetItems()
    {
        m_pListWidget = new QListWidget(this);
        QString listStyle(
            "QListWidget::item:hover,"
            "QListWidget::item:disabled:hover,"
            "QListWidget::item:hover:!active,"
            "{background:#FFFFFF;}");
    
        m_pListWidget->setStyleSheet(listStyle);
        m_pListWidget->setFixedSize(QSize(470, 150));
    
        for (const auto& jobName: m_pJobNames)
        {
           // std::shared_ptr<QListWidgetItem> listWidgetItem = std::make_shared<QListWidgetItem>(QString::fromStdString(jobName));
            QListWidgetItem* listWidgetItem = new QListWidgetItem(m_pListWidget);
            QCustomListWidgetItem* customListWidget = new QCustomListWidgetItem(jobName, m_pListWidget);
            listWidgetItem->setSizeHint(customListWidget->size());
            listWidgetItem->setFlags(listWidgetItem->flags() & ~Qt::ItemIsSelectable);
            m_pListWidget->addItem(listWidgetItem);
            m_pListWidget->setItemWidget(listWidgetItem, customListWidget);
        }
    }
    
    void UploadJobListDialog::removeit(size_t ui)
    {
        std::lock_guard<std::mutex> lock(a);
        for (int i = 0; i < m_pListWidget->count(); ++i)
        {
            sleep(10);
            QListWidgetItem* item = m_pListWidget->item(0);
            if (!item)
                continue;
    
            QCustomListWidgetItem* widget = dynamic_cast<QCustomListWidgetItem*>(m_pListWidget->itemWidget(item));
            if (!widget)
                continue;
    
            int nRow = m_pListWidget->row(item);
            QListWidgetItem* pDeleteItem = m_pListWidget->takeItem(nRow);
            if (pDeleteItem != NULL)
            {
                delete pDeleteItem;
            }
        }
    }
    
    int main(int argc, char *argv[])
    {
       QApplication a(argc, argv);
       std::vector<std::string> jobs = {"1","2","3","4","5"};
    
       static UploadJobListDialog obj(jobs);
    
       std::thread([=]
               {
                   obj.removeit(jobs.size());
               }
          ).detach();
    
       obj.exec();
    
        return 0;
    }
    
    

    Questions:

    1. What is leading to corruption?
    2. Am I doing something wrong?

    Ps: I am new to QT, any help is greatly appreciated.

    jsulmJ 1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      You are creating 2 objects when you add an item, but you only delete one.

      (Z(:^

      1 Reply Last reply
      0
      • K Krpadia123

        I am working on application, In which QDialog will be populated with some Custom ListWidgetItem labeled from 1 to 5, now in application requirement is that some other thread will delete the Items from dialog.

        Problem:
        As soon as first Item is deleted, it will corrupt the next item. (I can see blank item in dialog)
        ![alt text](1629eeee-ec24-4b69-80c1-322f68c43433-Screenshot (107).png image url)

        Note : Using Custom ListWidgetItem is important to make it scalable later.

        Code:

        1. mainwindow.h
        #ifndef MAINWINDOW_H
        #define MAINWINDOW_H
        
        #include <QMainWindow>
        #include <QtWidgets/QDialog>
        #include <QtWidgets/QListWidget>
        #include <QLabel>
        
        
        QT_BEGIN_NAMESPACE
        namespace Ui { class MainWindow; }
        QT_END_NAMESPACE
        
        class MainWindow : public QMainWindow
        {
            Q_OBJECT
        
        public:
            MainWindow(QWidget *parent = nullptr);
            ~MainWindow();
        
        private:
            Ui::MainWindow *ui;
        };
        #endif // MAINWINDOW_H
        
        
        //Custom WidgetItem
        class UploadJobListDialog : public QDialog
        {
            Q_OBJECT
        public:
            explicit UploadJobListDialog(std::vector<std::string> jobNames, QWidget* parent = NULL);
            void removeit(size_t i);
        
        
        private:
            void addListWidgetItems();
            QListWidget* m_pListWidget = nullptr;
        
            std::vector<std::string> m_pJobNames = {};
        
        };
        
        class QCustomListWidgetItem : public QWidget
        {
            Q_OBJECT
            public:
                explicit QCustomListWidgetItem(std::string labelText, QWidget* parent = NULL);
        
            private:
        
                QLabel* m_pItemLabel = nullptr;
                std::string m_pJobName;
        };
        
        
        1. main.cpp
        #include "mainwindow.h"
        #include <QApplication>
        #include <QHBoxLayout>
        #include <thread>
        #include <unistd.h>
        #include <mutex>
        
        std::mutex a;
        
        QCustomListWidgetItem::QCustomListWidgetItem(std::string labelText, QWidget* parent)
        : QWidget(parent), m_pJobName(labelText)
        {
            m_pItemLabel = new QLabel(QString::fromStdString(m_pJobName), this);
        }
        
        
        
        UploadJobListDialog::UploadJobListDialog(std::vector<std::string> jobNames, QWidget* parent)
            : QDialog(parent) , m_pJobNames(jobNames)
        {
            addListWidgetItems();
        }
        
        void UploadJobListDialog::addListWidgetItems()
        {
            m_pListWidget = new QListWidget(this);
            QString listStyle(
                "QListWidget::item:hover,"
                "QListWidget::item:disabled:hover,"
                "QListWidget::item:hover:!active,"
                "{background:#FFFFFF;}");
        
            m_pListWidget->setStyleSheet(listStyle);
            m_pListWidget->setFixedSize(QSize(470, 150));
        
            for (const auto& jobName: m_pJobNames)
            {
               // std::shared_ptr<QListWidgetItem> listWidgetItem = std::make_shared<QListWidgetItem>(QString::fromStdString(jobName));
                QListWidgetItem* listWidgetItem = new QListWidgetItem(m_pListWidget);
                QCustomListWidgetItem* customListWidget = new QCustomListWidgetItem(jobName, m_pListWidget);
                listWidgetItem->setSizeHint(customListWidget->size());
                listWidgetItem->setFlags(listWidgetItem->flags() & ~Qt::ItemIsSelectable);
                m_pListWidget->addItem(listWidgetItem);
                m_pListWidget->setItemWidget(listWidgetItem, customListWidget);
            }
        }
        
        void UploadJobListDialog::removeit(size_t ui)
        {
            std::lock_guard<std::mutex> lock(a);
            for (int i = 0; i < m_pListWidget->count(); ++i)
            {
                sleep(10);
                QListWidgetItem* item = m_pListWidget->item(0);
                if (!item)
                    continue;
        
                QCustomListWidgetItem* widget = dynamic_cast<QCustomListWidgetItem*>(m_pListWidget->itemWidget(item));
                if (!widget)
                    continue;
        
                int nRow = m_pListWidget->row(item);
                QListWidgetItem* pDeleteItem = m_pListWidget->takeItem(nRow);
                if (pDeleteItem != NULL)
                {
                    delete pDeleteItem;
                }
            }
        }
        
        int main(int argc, char *argv[])
        {
           QApplication a(argc, argv);
           std::vector<std::string> jobs = {"1","2","3","4","5"};
        
           static UploadJobListDialog obj(jobs);
        
           std::thread([=]
                   {
                       obj.removeit(jobs.size());
                   }
              ).detach();
        
           obj.exec();
        
            return 0;
        }
        
        

        Questions:

        1. What is leading to corruption?
        2. Am I doing something wrong?

        Ps: I am new to QT, any help is greatly appreciated.

        jsulmJ Offline
        jsulmJ Offline
        jsulm
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @Krpadia123 said in [QT6][C++] Deleting item from Custom ListWidgetItem corrupting other entry in QT:

        std::lock_guardstd::mutex lock(a);

        You should use signals/slots between threads in Qt, then there is no need for synchronisation. It is not supported to manipulate UI from other threads than the UI thread!
        Your other thread should emit a signal with the item index to delete as parameter. In your dialog make UploadJobListDialog::removeit(size_t ui) a slot. Then connect the signal with slot. When the other thread wants to delete an item it simply emits the signal.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        1 Reply Last reply
        2
        • K Offline
          K Offline
          Krpadia123
          wrote on last edited by
          #4

          @jsulm Thank you soo much, its working perfectly with signal/slots.
          Thank you again!

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved