Файлы такие:
//g++ main.cc -o main `pkg-config gtkmm-3.0 --cflags --libs` -lstdc++fs
#include "mainwindow.cc"
#include "catalog.cc"
#include "mainwindow.h"
#include <gtkmm/application.h>
int main(int argc, char *argv[])
{
auto app = Gtk::Application::create("org.gtkmm.example");
MainWindow window;
return app->run(window, argc, argv);
}
#ifndef GTKMM_MAINWINDOW_H
#define GTKMM_MAINWINDOW_H
#include <gtkmm.h>
#include "catalog.h"
class MainWindow : public Gtk::Window
{
public:
MainWindow();
virtual ~MainWindow();
protected:
void add_catalog();
//Child widgets:
Gtk::Box m_mainBox;
Gtk::Grid m_grid;
Catalog *m_Catalog0 = new Catalog("/var/www/cscart.site");
Catalog *m_Catalog1 = new Catalog("/var/www");
Catalog *m_Catalog2 = new Catalog("/var/www/cscart.site");
Catalog *m_Catalog3 = new Catalog("/var/www");
Gtk::ButtonBox m_bottom_buttons_box;
Gtk::Button m_button_add;
};
#endif //GTKMM_MAINWINDOW_H
#include "mainwindow.h"
MainWindow::MainWindow()
: m_mainBox(Gtk::ORIENTATION_VERTICAL),
m_button_add("+")
{
set_title("FM 4x4");
set_border_width(5);
set_default_size(500, 500);
add(m_mainBox);
m_mainBox.pack_start(m_grid);
m_grid.attach(*m_Catalog0, 0, 0, 1, 1);
m_grid.attach(*m_Catalog1, 1, 0, 1, 1);
m_grid.attach(*m_Catalog2, 1, 1, 1, 1);
m_grid.remove(*m_Catalog0);
m_grid.attach(*m_Catalog0, 0, 0, 1, 2);
m_mainBox.pack_start(m_bottom_buttons_box, Gtk::PACK_SHRINK);
m_bottom_buttons_box.pack_start(m_button_add, Gtk::PACK_SHRINK);
m_bottom_buttons_box.set_border_width(5);
m_bottom_buttons_box.set_layout(Gtk::BUTTONBOX_END);
m_button_add.signal_clicked().connect( sigc::mem_fun(*this, &MainWindow::add_catalog) );
show_all_children();
}
MainWindow::~MainWindow() {
}
void MainWindow::add_catalog() {
//m_leftBox.pack_start(*m_Catalog3);
m_grid.remove(*m_Catalog0);
show_all_children();
}
#ifndef GTKMM_MAIN_CATALOG_H
#define GTKMM_MAIN_CATALOG_H
#include <gtkmm.h>
class Catalog: public Gtk::ScrolledWindow {
public:
Catalog(std::string p);
virtual ~Catalog();
void set_path(std::string p);
class ModelColumns : public Gtk::TreeModel::ColumnRecord {
public:
ModelColumns() {
add(m_col_name); add(m_col_extension_or_dir_or_file);
}
Gtk::TreeModelColumn<std::string> m_col_name;
Gtk::TreeModelColumn<std::string> m_col_extension_or_dir_or_file;
};
ModelColumns m_Columns;
Gtk::TreeView m_TreeView;
protected:
Glib::RefPtr<Gtk::ListStore> m_refListStore; //The Tree Model.
};
#endif //GTKMM_EXAMPLE_MESSAGESLIST_H
#include "catalog.h"
#include <experimental/filesystem>
Catalog::Catalog(std::string p) {
set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
set_hexpand(true);
set_vexpand(true);
/* Обязательно поправить это недоразумение */
set_border_width(1);
add(m_TreeView);
m_refListStore = Gtk::ListStore::create(m_Columns);
m_TreeView.set_model(m_refListStore);
Gtk::TreeModel::Row row;
namespace fs = std::experimental::filesystem;
std::string path = p;
for (auto & p : fs::directory_iterator(path)) {
row = *(m_refListStore->append());
row[m_Columns.m_col_name] = fs::path(p).filename();
row[m_Columns.m_col_extension_or_dir_or_file] = fs::path(p);
}
m_TreeView.append_column("Name", m_Columns.m_col_name);
m_TreeView.append_column("Extension",
m_Columns.m_col_extension_or_dir_or_file);
}
Catalog::~Catalog() {
}
А вопрос такой:
Я хочу эти 4 экземпляра:
Catalog *m_Catalog0 = new Catalog("/var/www/cscart.site");
Catalog *m_Catalog1 = new Catalog("/var/www");
Catalog *m_Catalog2 = new Catalog("/var/www/cscart.site");
Catalog *m_Catalog3 = new Catalog("/var/www");
заменить вектором класса. Как мне это сделать?
конструкция вида:
std::vector{Catalog^} arr;
arr.push_back(new A(2));
arr[0];
не работает.
Хотя тестовый файл с такой конструкцией отрабатывает нормально.
Определение вектора в классе вполне обычное:
class MainWindow : public Gtk::Window {
public:
MainWindow();
//...
std::vector<Catalog*> catalogVec;
}
Для инициализации классическим решением будет несколько push_back'ов в конструкторе:
MainWindow::MainWindow() /* : ... */ {
catalogArr.push_back(new Catalog("/var/www/cscart.site"));
catalogArr.push_back(new Catalog("/var/www"));
// ...
}
В новых версиях C++ есть также варианты:
Инициализация при объявлении:
class MainWindow : public Gtk::Window {
//...
std::vector<Catalog*> catalogVec = { new Catalog("/var/www/cscart.site"),
new Catalog("/var/www"}
};
}
Инициализация в списке инициализации конструктора:
MainWindow::MainWindow() :
// ...
catalogVec ({new Catalog("/var/www/cscart.site"), new Catalog("/var/www")});
{
// ...
}
Но при таком подходе ответственность за указатели лежит на программисте. И эти объекты необходимо явно уничтожить в деструкторе (если конечно gtkmm об этом само не заботится как Qt; TODO: свериться с документацией).
MainWindow::~MainWindow() {
for (auto cat: catalogveg) {
delete cat;
}
}
Вместо этого я бы рекомендовал использовать std::unique_ptr.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей