Векторы в gtkmm 3.0 [закрыт]

157
26 апреля 2019, 10:10

Файлы такие:

main.cc

//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);
}

mainwindow.h

#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

mainwindow.cc

#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();
}

catalog.h

#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

catalog.cc

#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];  

не работает.

Хотя тестовый файл с такой конструкцией отрабатывает нормально.

Answer 1

Определение вектора в классе вполне обычное:

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.

READ ALSO
Как тестировать парсер?

Как тестировать парсер?

Нужно написать парсер на основе Lex/Yacc (точнее, Flex/Bison) для небольшого скриптового языкаСама задача достаточно понятная, но совершенно непонятно,...

128
Как избавиться от утечки памяти

Как избавиться от утечки памяти

Есть код, при рантайме выдает ошибку сегментации:

127
C++ 14 constexpr std::array

C++ 14 constexpr std::array

Изучаю constexprНе могу понять, почему компилятор не рассматривает одно из выражений как константное, потому что оно подходит под требования

128
CryptEncodeObjectEx segfault при обращении

CryptEncodeObjectEx segfault при обращении

CryptEncodeObjectEx разваливается при обращении, параметры не влияют, как выяснилосьСобираю gcc-tdm, через Code::Blocks, что опробовано:

126