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. Crash using QListWidget
QtWS25 Last Chance

Crash using QListWidget

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 3 Posters 478 Views
  • 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.
  • J Offline
    J Offline
    Jesus C Risq
    wrote on last edited by Jesus C Risq
    #1

    Good afternoon,

    I am having problems with a widget. The widget and its code is as follows:

    ![alt text](image https://ibb.co/FzrvpQL)

    Below the "+" and "-" buttons there are 2 QListWidget where custom widgets are inserted, being these QListWidget as follows:

    ![alt text](image https://ibb.co/d7xnghc)

    The problem comes that when I try to add a new widget to the QListWidget, it crashes and closes everything. I have managed to find out that when they are going to insert the widget in one of the lists, the memory address of the lists has changed and that's where the crashes come from. But I can't understand the reason. And Image of problem:

    ![alt text](image https://ibb.co/rtgn9Wc)

    The code is the following:

    DataTypeListWidget.h

    #ifndef DATATYPELISTWIDGET_H
    #define DATATYPELISTWIDGET_H
    
    #include <QWidget>
    #include <QListWidget>
    #include <QListWidgetItem>
    
    #include "ItemDataTypeWidget.h"
    
    class DataTypeListWidget : public QWidget
    {
        Q_OBJECT
    public:
        DataTypeListWidget( QWidget* parent = nullptr );
    
        void AddNewWidget( QWidget* newWidget );
    
    public:
        QListWidget* _list;
        QHBoxLayout* layout;
    };
    
    #endif // DATATYPELISTWIDGET_H
    

    DataTypeListWidget.cpp

    #include "DataTypeListWidget.h"
    #include <QDebug>
    
    DataTypeListWidget::DataTypeListWidget(QWidget *parent)
        : QWidget( parent )
        , _list( new QListWidget( this ) )
    {
        layout = new QHBoxLayout( );
        layout->addWidget( _list );
    }
    
    void DataTypeListWidget::AddNewWidget(QWidget *newWidget )
    {
        QListWidgetItem* item = new QListWidgetItem( );
        _list->insertItem( _list->count(), item );
        item->setSizeHint( newWidget->sizeHint() );
        _list->setItemWidget( item, newWidget );
        layout->setSizeConstraint( QLayout::SetFixedSize );
        this->setMinimumSize( layout->sizeHint() );
    }
    

    SceneContainerConfigWindow.h

    #ifndef SCENECONTAINERCONFIGWINDOW_H
    #define SCENECONTAINERCONFIGWINDOW_H
    
    #include <QWidget>
    #include <QPushButton>
    #include <QLabel>
    #include <QHBoxLayout>
    #include <QVBoxLayout>
    #include <QGridLayout>
    
    #include "DataTypeListWidget.h"
    #include "QDebug"
    
    class SceneContainerConfigWindow : public QWidget
    {
        Q_OBJECT
    public:
        explicit SceneContainerConfigWindow( QWidget* parent = nullptr );
        void BuildWidget();
        void BuildLogic();
    
    public slots:
        void AddInput();
        void AddOutput();
    
    protected:
        ItemDataTypeWidget* MakeNewItem( int pos, QStringList options );
    
    protected:
    
        QPushButton* apply;
        QPushButton* cancel;
    
        QPushButton* add_input;
        QPushButton* add_output;
        QPushButton* delete_input;
        QPushButton* delete_output;
    
        DataTypeListWidget* inputs_list;    int _input_count;
        DataTypeListWidget* outputs_list;   int _output_count;
    
        QLabel* input_label;
        QLabel* output_label;
    
        QHBoxLayout* actionsbuttons_layouts;
        QHBoxLayout* inputs_labes_layouts;
        QHBoxLayout* listwidgets_layouts;
        QHBoxLayout* add_delete_itemsList_layout;
        QGridLayout* p_layout;
    
        QVBoxLayout* main_layout;
    
        QStringList _options;
    
    };
    
    #endif // SCENECONTAINERCONFIGWINDOW_H
    

    SceneContainerConfigWindow.cpp

    #include "SceneContainerConfigWindow.h"
    
    SceneContainerConfigWindow::SceneContainerConfigWindow(QWidget *parent)
        : QWidget( parent )
        , _input_count( 0 ), _output_count( 0 )
    {
        BuildWidget();
        BuildLogic();
    }
    
    void SceneContainerConfigWindow::BuildWidget()
    {
        _options << "decimal" << "string";
    
        // First widgets level
        input_label     = new QLabel( " INPUTS ", this );
        output_label    = new QLabel( " OUTPUTS ", this );
    
        // Second widgets level
        add_input = new QPushButton( this );
        delete_input = new QPushButton( this );
    
        add_output = new QPushButton( this );
        delete_output = new QPushButton( this );
    
        p_layout = new QGridLayout();
        p_layout->addWidget( input_label, 0, 0, 1, 2 );
        p_layout->addWidget( output_label, 0, 2, 1, 2 );
    
        p_layout->addWidget( add_input, 1, 0, 1, 1 );
        p_layout->addWidget( delete_input, 1, 1, 1, 1 );
        p_layout->addWidget( add_output, 1, 2, 1, 1 );
        p_layout->addWidget( delete_output, 1, 3, 1, 1 );
    
    
        // Thirst widgets level
        DataTypeListWidget* inputs_list     = new DataTypeListWidget( this );
        DataTypeListWidget* outputs_list    = new DataTypeListWidget( this );
    
        inputs_list->setMinimumSize( 200, 300 );
        inputs_list->setMaximumSize( 5000, 5000 );
        inputs_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    
        outputs_list->setMinimumSize( 200, 300 );
        outputs_list->setMaximumSize( 5000, 5000 );
        outputs_list->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        listwidgets_layouts = new QHBoxLayout();
        listwidgets_layouts->addWidget( inputs_list );
        listwidgets_layouts->addWidget( outputs_list );
    
        // Four widgets level
        apply  = new QPushButton( "APPLY", this );
        cancel  = new QPushButton( "CANCEL", this );
    
        actionsbuttons_layouts = new QHBoxLayout();
        actionsbuttons_layouts->addSpacing( 150 );
        actionsbuttons_layouts->addWidget( cancel );
        actionsbuttons_layouts->addWidget( apply );
    
        // Adding all layout to widget
        main_layout = new QVBoxLayout();
        main_layout->addLayout( p_layout );
        main_layout->addLayout( listwidgets_layouts );
        main_layout->addLayout( actionsbuttons_layouts );
    
        this->setLayout( main_layout );
    
        this->setFixedSize( 520, 300 );
    
        qDebug() << "Input_List MEM DIR " << &inputs_list->_list;
        qDebug() << "Output_List MEM DIR " << &outputs_list->_list;
    
    }
    
    void SceneContainerConfigWindow::BuildLogic()
    {
    
        connect( add_input, &QPushButton::clicked,
                       this, &SceneContainerConfigWindow::AddOutput );
    
        connect( add_output, &QPushButton::clicked,
                 this, &SceneContainerConfigWindow::AddOutput );
    
        qDebug() << "Input_List MEM DIR " << &inputs_list->_list;
        qDebug() << "Output_List MEM DIR " << &outputs_list->_list;
    }
    
    void SceneContainerConfigWindow::AddInput()
    {
        _input_count++;
        ItemDataTypeWidget* item = new ItemDataTypeWidget(  );
        item->SetInfo( _input_count, _options );
        inputs_list->AddNewWidget( item );
    }
    
    void SceneContainerConfigWindow::AddOutput()
    {
        _output_count++;
        outputs_list->AddNewWidget( MakeNewItem( _output_count, _options ) );
    }
    
    ItemDataTypeWidget*
    SceneContainerConfigWindow::MakeNewItem(int pos, QStringList options)
    {
        ItemDataTypeWidget* item = new ItemDataTypeWidget();
        item->SetInfo( pos, options );
        return item;
    }
    

    ItemDataTypeWidget.h

    #ifndef ITEMDATATYPEWIDGET_H
    #define ITEMDATATYPEWIDGET_H
    
    #include <QWidget>
    #include <QLabel>
    #include <QListWidget>
    #include <QListWidgetItem>
    #include <QComboBox>
    #include <QHBoxLayout>
    
    class ItemDataTypeWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit ItemDataTypeWidget( QWidget * parent = nullptr );
        void SetInfo( int input_number, QStringList types_list );
    
    protected:
        void BuildWidget();
    
    protected:
        QLabel* label;
        QComboBox* type;
        QHBoxLayout* layout;
    
    };
    #endif // ITEMDATATYPEWIDGET_H
    

    ItemDataTypeWidget.cpp

    #include "ItemDataTypeWidget.h"
    
    
    ItemDataTypeWidget::ItemDataTypeWidget(QWidget* parent)
        : QWidget( parent )
    {
        BuildWidget();
    }
    
    void ItemDataTypeWidget::BuildWidget()
    {
        label = new QLabel( "Input", this );
        type = new QComboBox( this );
        layout = new QHBoxLayout();
    
        layout->addWidget( label );
        layout->addSpacing( 10 );
        layout->addWidget( type );
        layout->addStretch();
        layout->setSizeConstraint( QLayout::SetFixedSize );
        this->setLayout( layout );
    }
    
    void ItemDataTypeWidget::SetInfo(int input_number, QStringList types_list)
    {
        label->setText( "Input " + QString::number(input_number) );
        type->addItems( types_list );
        layout->setSizeConstraint( QLayout::SetFixedSize );
    }
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Please show/take a look at the backtrace to see where it really crashes.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • J Offline
        J Offline
        Jesus C Risq
        wrote on last edited by Jesus C Risq
        #3

        @Christian-Ehrlicher, Here is an image of the debugger. I don't know if this is exactly what you meant. From what I see in the debugger, it fails to use the QListWidget class. It seems to me that the failure comes because that pointer with the class does not exist.

        The crash occurs in the AddNewWidget method of the DataTypeListWidget class.

        ![alt text](image https://ibb.co/Q6DSmrD)

        In the following image,
        ![alt text](image https://ibb.co/j8M9pGh)

        I print with debug messages the memory address of the QListWidget. The curious thing is that in the third call the memory address is different. I think that there is the failure, it tries to access an invalid memory address. But I don't understand the reason, because the constructor does instantiate the class.

        1 Reply Last reply
        0
        • Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          We can't see your images and you still don't tell us where exactly it crashes from your code.

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          1 Reply Last reply
          1
          • J Offline
            J Offline
            Jesus C Risq
            wrote on last edited by
            #5

            Sorry, I didn't realize that the images are not visible. I have re-uploaded the images. I hope they are visible now.

            JonBJ 1 Reply Last reply
            0
            • J Jesus C Risq

              Sorry, I didn't realize that the images are not visible. I have re-uploaded the images. I hope they are visible now.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #6

              @Jesus-C-Risq
              How do we/you know which instance of a DataTypeListWidget you are printing the address of _list from? If you're going to be printing addresses I'd include &this in your debug output.

              1 Reply Last reply
              0
              • Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Your first image clearly show that the this pointer is a nullptr. So your pointer to DataTypeListWidget in AddNewWidget is a nullptr.
                Using a debugger should be a base skill btw - I suggest you to learn such stuff, otherwise debugging and fixing problems will become a pain.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                JonBJ 1 Reply Last reply
                1
                • Christian EhrlicherC Christian Ehrlicher

                  Your first image clearly show that the this pointer is a nullptr. So your pointer to DataTypeListWidget in AddNewWidget is a nullptr.
                  Using a debugger should be a base skill btw - I suggest you to learn such stuff, otherwise debugging and fixing problems will become a pain.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @Christian-Ehrlicher said in Crash using QListWidget:

                  Your first image clearly show that the this pointer is a nullptr

                  Damn, you spot simple things quicker than I do :)
                  Same point @Jesus-C-Risq though: you need to thinking about the instances of what you're printing out. And here the instance is, well, rubbish :)

                  1 Reply Last reply
                  0
                  • J Offline
                    J Offline
                    Jesus C Risq
                    wrote on last edited by
                    #9

                    I have already found the bug. In the end it was a silly thing, but as much as I checked the code I didn't see it.

                    The problem was in the SceneContainerConfigWindow class. In the BuildWidget() method these two lines were wrong:

                        DataTypeListWidget* inputs_list     = new DataTypeListWidget( this );
                        DataTypeListWidget* outputs_list    = new DataTypeListWidget( this );
                    

                    Changing them for the following ones fixes it.

                        inputs_list     = new DataTypeListWidget( this );
                        outputs_list    = new DataTypeListWidget( this );
                    

                    The classes were instantiated but not assigned to any pointer, that's why the "inputs_list" address was empty.

                    Thank you very much for the help and I take the advice to learn about debugger.

                    1 Reply Last reply
                    0

                    • Login

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