In the process of studying Qt I ran into a small problem, there is a program "Browser", it is written in the main() function in the book, everything works as it should, I want to write this code into a separate file / class inherited from QSplitter , it does not generate an error, but starts with an empty window. enter image description here

code itself:

 Splitter::Splitter(QSplitter* parent) : QSplitter(Qt::Horizontal, parent) { QFileSystemModel model; model.setRootPath(QDir::rootPath()); QTreeView* pTreeView = new QTreeView; pTreeView->setModel(&model); QTableView* pTableView = new QTableView; pTableView->setModel(&model); QObject::connect(pTreeView, SIGNAL(clicked(const QModelIndex&)), pTableView, SLOT(setRootIndex(const QModelIndex&))); QObject::connect(pTableView, SIGNAL(activated(const QModelIndex&)), pTreeView, SLOT(setCurrentIndex(const QModelIndex&))); QObject::connect(pTableView, SIGNAL(activated(const QModelIndex&)), pTableView, SLOT(setRootIndex(const QModelIndex&))); addWidget(pTreeView); addWidget(pTableView); resize(600, 400); setWindowTitle("Файловый менеджер"); } 

    2 answers 2

    QFileSystemModel model - this object exists only within the constructor. You pass it to the setModel method, but after exiting the constructor, this object is restructured and QTableView and QTreeView remain without a model, hence all the problems.

    Make model pointer to a QFileSystemModel and allocate memory for it dynamically.

     Splitter::Splitter(QSplitter* parent) : QSplitter(Qt::Horizontal, parent) { QFileSystemModel * model = new QFileSystemModel; model->setRootPath(QDir::rootPath()); QTreeView* pTreeView = new QTreeView; pTreeView->setModel(model); QTableView* pTableView = new QTableView; pTableView->setModel(model); QObject::connect(pTreeView, SIGNAL(clicked(const QModelIndex&)), pTableView, SLOT(setRootIndex(const QModelIndex&))); QObject::connect(pTableView, SIGNAL(activated(const QModelIndex&)), pTreeView, SLOT(setCurrentIndex(const QModelIndex&))); QObject::connect(pTableView, SIGNAL(activated(const QModelIndex&)), pTableView, SLOT(setRootIndex(const QModelIndex&))); addWidget(pTreeView); addWidget(pTableView); resize(600, 400); setWindowTitle("Файловый менеджер"); } 

    But do not forget about memory leaks, in which case they are provided. As an option, store all pointers as members of a class, and delete them in the destructor.

    • In this case, specify the current widget (this) as the parent of the model and the views then Qt will take care of the correct cleaning itself - I stand alone
    • one
      With a leak figured out! Everything works as it should! - Andrei Salamov

    And why so inherited from the splitter? You do not add any new functionality to it. In addition, the task of the splitter, as the name implies, is only to display something with a dividing strip that can be moved, reducing / increasing the widgets that are in it. Most likely, you need to make a window class - either Widget, or MainWindow, which will have all this functionality. The splitter can be made the central window widget.

      class MainWindow : public QMainWidget { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr) { model_ = new QFileSystemModel(this); model_->setRootPath(QDir::rootPath()); pTreeView_ = new QTreeView(this); pTreeView_->setModel(model); pTableView_ = new QTableView(this); pTableView_->setModel(model); // connect signal slots mainSplitter_->addWidget(pTreeView_); mainSplitter_->addWidget(pTableView_); setMCentralWidget(mainSplitter_); resize(600, 400); setWindowTitle("Файловый менеджер"); } private: //... QFileSystemModel *model_; QTreeView *pTreeView_; QTableView *pTableView_; QSplitter *mainSplitter_; } 

    PS and as they say Eric and Elizabeth Freeman composition is often preferable to inheritance. Great book, I advise.