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. Can I instantiate new objects in QObject constructors?
Forum Updated to NodeBB v4.3 + New Features

Can I instantiate new objects in QObject constructors?

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 2 Posters 346 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.
  • N Offline
    N Offline
    NullFunction
    wrote on last edited by
    #1

    Hi,

    In my current project, I'm having a main QWidget which has a QTableView as attribute and several buttons. When I run valgrind (memcheck), it complains about some memory here and there, which I outlined. Both TableView and QtModel inherit from Qt objects (QTableView and QAbstractTableModel respectively), with Q_OBJECT in the class definition for both as well (h files at the bottom).

    My understanding is that they're supposed to be cleaned up when the main widget is closed but there seems to be lingering memory, why?

    I'm using it like that (abridged):

    .h file:

    class View : public QWidget {
      Q_OBJECT
    public:
      explicit View(QWidget *parent = nullptr);
      void setModel(QtModel *model);
      void connectToModel();
      void pickFirstPlayer();
      QLabel *createLabel(const QString &str);
    
    private:
      TableView *m_table = nullptr; // A subclass of QTableView
      QtModel *m_model = nullptr;
      QGridLayout *layout;
      QLCDNumber *redVictoryPoints;
      QLCDNumber *blackVictoryPoints;
      QLCDNumber *turns;
      QLabel *gameState = new QLabel("Pick a player!");
    

    .cpp file:

    View::View(QWidget *parent) : QWidget{parent} {
      layout = new QGridLayout;
      setLayout(layout);
      m_table = new TableView; // OFFENDING CODE?
      // show useful data and set items within layout
      redVictoryPoints = new QLCDNumber(2);
      blackVictoryPoints = new QLCDNumber(2);
      turns = new QLCDNumber(1);
      turns->setMaximumHeight(35);
      layout->addWidget(
          m_table, 0, 0, 9,
          9); // 9 x 9 grid because there are 9 buttons per stack and 9 stacks
      layout->addWidget(createLabel(tr("TURNS")), 10, 0);
      layout->addWidget(turns, 10, 1);
      layout->addWidget(createLabel(tr("RED VICTORY POINTS")), 10, 3);
      layout->addWidget(redVictoryPoints, 10, 4);
      layout->addWidget(createLabel(tr("BLACK VICTORY POINTS")), 10, 6);
      layout->addWidget(blackVictoryPoints, 10, 7);
      layout->addWidget(createLabel(tr("GAME STATE")), 0, 10);
      layout->addWidget(gameState, 1, 10);
      gameState->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
      // --- Add the game and model ---// 
      Game *g{new Game};
      m_model = new QtModel; // OFFENDING CODE?
      m_model->setGame(g);
      setModel(m_model);
      connectToModel();
    

    N.B: headers
    QtModel.h:

    #ifndef QTMODEL_H
    #define QTMODEL_H
    #include "game.h"
    #include <QAbstractTableModel>
    
    class QtModel : public QAbstractTableModel {
      Q_OBJECT
    
    public:
      explicit QtModel(QObject *parent = nullptr);
    
      // Header data
    
      QVariant headerData(int section, Qt::Orientation orientation,
                          int role) const override;
    
      // Basic functionality:
      int rowCount(const QModelIndex &parent = QModelIndex()) const override;
      int columnCount(const QModelIndex &parent = QModelIndex()) const override;
    
      QVariant data(const QModelIndex &index,
                    int role = Qt::DisplayRole) const override;
    
      void setGame(Game *game);
      Game *getGame();
      void setState(Game::GameState);
    
    public slots:
      void moveStacksOnColumnClicked(const QModelIndex &idx);
      void replay();
    
    private:
      Game *m_game = nullptr;
    
    signals:
      void turnChanged(int turns);
      void stateChanged(Game::GameState);
      void redTally(int);
      void blackTally(int);
      void roundTally(int, int);
      void endGame(int, int);
    };
    #endif // QTMODEL_H
    

    TableView.h:

    #ifndef TABLEVIEW_H
    #define TABLEVIEW_H
    
    #include <QTableView>
    
    class TableView : public QTableView {
      Q_OBJECT
    public:
      TableView();
    };
    
    
    #endif // TABLEVIEW_H
    
    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on last edited by
      #2

      When I run valgrind (memcheck), it complains about some memory here and there, which I outlined.

      Where?

      Child QObjects are deleted when the parent is deleted. QWidget::close() does not delete the object under default conditions, although it can.

      The TableView object allocated on the line marked "OFFENDING CODE" is unparented until a few lines later when you add it to the layout, which has the effect of setting its parent for you. This memory will be freed when the parent object is (same true for the QLCDNumber objects).

      The model object marked "OFFENDING CODE" is unparented and may stay that way depending on what View::setModel() is doing.

      N 1 Reply Last reply
      2
      • C ChrisW67

        When I run valgrind (memcheck), it complains about some memory here and there, which I outlined.

        Where?

        Child QObjects are deleted when the parent is deleted. QWidget::close() does not delete the object under default conditions, although it can.

        The TableView object allocated on the line marked "OFFENDING CODE" is unparented until a few lines later when you add it to the layout, which has the effect of setting its parent for you. This memory will be freed when the parent object is (same true for the QLCDNumber objects).

        The model object marked "OFFENDING CODE" is unparented and may stay that way depending on what View::setModel() is doing.

        N Offline
        N Offline
        NullFunction
        wrote on last edited by
        #3

        @ChrisW67

        Where I added the comments with the offending code.

        I had to set the parents of some of the objects because it actually did not cleanup when the objects were destroyed, contrary to expectations.

        One of the error was on me because my game class wasn't properly destructed (and isn't a Qt object).

        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