В процессе изучения Qt столкнулся с небольшой проблемой, есть программа "Обозреватель", она в книге написана в функции main()
, все работает как надо, я же хочу этот код вписать в отдельный файл/класс унаследованный от QSplitter
, ошибку не выдает, но запускается с пустым окном.
сам код:
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("Файловый менеджер");
}
QFileSystemModel model
- этот объект существует лишь в пределах конструктора.
Вы передаете его адресс в метод setModel
, но после выхода из конструктора этот объект деструктурируется и QTableView
и QTreeView
остаются без модели, отсюда все проблемы.
Сделайте model
указателем на QFileSystemModel
и распределите для него динамически память.
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("Файловый менеджер");
}
Но не забывайте про утечки памяти, в таком случае они обеспечены. Как вариант - хранить все указатели как члены класса, а в деструкторе их удалять.
А зачем так наследоваться от сплиттера? Вы же не добавляете никакую новую функциональность в него. К тому же задача сплиттера, как следует из названия, всего лишь отобразить нечто с разделительной полосой, которую можно двигать, уменьшая/увеличивая виджеты, которые в нем есть. Скорее всего, вам нужно сделать класс окна - либо Widget, либо MainWindow, в котором будет весь этот функционал. Сплиттер можно сделать центральным виджетом окна.
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_;
}
P.S. и как говорят Эрик и Элизабет Фримен композиция зачастую предпочтительнее наследования. Отличная книга, советую.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Что такое lvalue to rvalue conversion? В этой статье непонятно следующее:
Можно ли писать приложения под Android на c++ с qt в Linux и какие для этого нужны компоненты?
Представление строит свой презентер, презентер получает ссылку на IView и строит свою модельВопрос: где строить подчиненные IView, в презентере...
Начал изучать книгу Эрика и Элизабет Фримен Паттерны проектированияПытаюсь написать на C++ архитектуру из первой главы