簡體   English   中英

QFileSystemModel 對象會被刪除嗎?

[英]Do QFileSystemModel objects ever get deleted?

我有一個經典的 QDialog,它使用 QFileSystemModel 填充 QTreeView,並有一個 function 來過濾和處理用戶選擇的項目列表。 我是 C++ 和 Qt 的新手,所以我一直在關注大量的在線教程和示例。 代碼最終看起來像這樣[為簡潔起見,對內容進行了匿名和編輯]:

在 header 文件中:

class MyExampleDialog : public QDialog
{
    Q_OBJECT

    public:
        explicit MyExampleDialog(MyMainWidget *parent = nullptr);
        ~MyExampleDialog();

    public slots:
        virtual void accept() override;

    private slots:
        void directoryPathEntered();
        void checkDirectoryPathAndUpdateTree(const QString& pathToCheck);
        void validateSelection();

    private:
        QString getDirectoryPath() const;
        QStringList updateFileSelection();

        Ui::MyExampleDialog *_ui;
};

並在源文件中:

MyExampleDialog::MyExampleDialog(MyMainWidget *parent) :
    QDialog(parent),
    _ui(new Ui::MyExampleDialog)
{
    _ui->setupUi(this);
    _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
    _ui->directoryPathEdit->setText(getDirectoryPath());
    checkDirectoryPathAndUpdateTree(getDirectoryPath());
    QObject::connect(_ui->browseButton, &QPushButton::pressed, this, &MyExampleDialog::directoryPathEntered);
    QObject::connect(_ui->directoryPathEdit, &QLineEdit::textChanged, this, &MyExampleDialog::checkDirectoryPathAndUpdateTree);
}

MyExampleDialog::~MyExampleDialog()
{
    delete _ui;
}

void MyExampleDialog::directoryPathEntered()
{
    const QString currentPath = getDirectoryPath();
    QString newPath = QFileDialog::getExistingDirectory(this, tr("Select the installation directory"), currentPath);
    if(newPath.isEmpty())
        return;

    _ui->directoryPathEdit->setText(newPath);
    // then write newPath to QSettings
}

QString MyExampleDialog::getDirectoryPath() const
{
    // retrieve path from QSettings
}

void MyExampleDialog::checkDirectoryPathAndUpdateTree(const QString& pathCheck)
{
    if(std::filesystem::exists(pathCheck.toStdString()+"/bin/config.xml"))
    {
        QStringList filters;
        filters << "*.jpeg";
        QFileSystemModel *model = new QFileSystemModel(this);
        model->setRootPath(pathCheck+QString::fromUtf8("/Images"));
        model->setReadOnly(true);
        model->setFilter(QDir::AllDirs | QDir::AllEntries | QDir::NoDotAndDotDot);
        model->setNameFilters(filters);
        _ui->imgTreeView->setModel(model);
        _ui->imgTreeView->setRootIndex(model->setRootPath("/Images"));
        _ui->imgTreeView->setSelectionMode(QAbstractItemView::ExtendedSelection);
        QObject::connect(_ui->imgTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MyExampleDialog::updateImgSelection);
        QObject::connect(_ui->imgTreeView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &MyExampleDialog::validateSelection);
    }
    else
    {
        if(pathCheck.isEmpty()) { }
        else
        {
            QMessageBox::critical(this, tr("Error"), tr("No config.xml file in installation /bin directory"));
        }
        _ui->imgTreeView->setModel(nullptr);
    }
}

QStringList MyExampleDialog::updateImgSelection()
{
    QItemSelectionModel *selModel = _ui->imgTreeView->selectionModel();
    QModelIndexList selIndices = selModel->selectedIndexes();
    QStringList imgSel;
    QFileSystemModel *fsModel = static_cast<QFileSystemModel*>(_ui->imgTreeView->model());

    foreach(QModelIndex index, selIndices)
    {
        // parse data to obtain file name
    }
    return imgSel;
}

void MyExampleDialog::validateSelection()
{
    QStringList imgList = updateImgSelection();
    if(! imgList.isEmpty())
    {
        _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
    }
    else { _ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false); }
}

void MyExampleDialog::accept()
{
    // do stuff when OK is clicked
}

請注意,在 function checkDirectoryPathAndUpdateTree中,我們使用new聲明了一個指向新 QFileSystemModel object 的指針。 此指針無法通過delete此 function 的 scope 中的刪除來刪除,因為我希望 model 持續存在,以便updateImgSelection可以使用它。 這似乎是 QFileSystemModel 對象的標准用法,但在 C++ 中,我們被教導永遠不要使用new實例化 object,而無需隨后使用delete來釋放 memory。 我的問題是 QFileSystemModel 的這種用法是否會導致 memory 泄漏,如果是,如何避免?

歡迎來到 C++ 和 Qt 的有趣世界。 您在將“新”與“刪除”配對時保持謹慎是正確的。 不過Qt的引擎為你做了很多object管理。

簡短的回答:這不會導致 memory 泄漏

更長的簡短答案:這不會導致 memory 泄漏。 您正在創建 object 並告訴 Qt 此 object 的父級是“this”。 Qt 現在讓您的 object 成為父子關系,“this”是父子關系,而新的 object 是子子關系。 當父級被刪除時,子級將隨之被刪除。

但是,請幫自己一個忙,花時間了解 Qt 如何處理對象以及何時由您來處理該實例。 如果您不這樣做,您可能會發現自己非常沮喪 memory 泄漏、看似隨機的崩潰或您認為應該存在的“丟失”對象。

祝你好運並堅持下去。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM