2017-11-26 1 views
1

TreeView를 사용하여 디렉토리의 내용을 나열하고 목록에서 파일 이름을 선택하려고합니다. 나는 파일 선택기 대화 상자를 사용하여 사용자 액세스를 한 디렉토리로 제한하고 이들이 시스템 주위를 탐색하지 못하도록하고 싶지 않습니다. 목록을 지우고 업데이트 할 때까지 내 코드가 제대로 작동합니다.Gtkmm3 TreeView ListStore.Clear 또는 TreeSelection.unselectAll 오류가 발생합니다.

은 Gtk-CRITICAL ** : gtk_list_store_get_value : 주장 'iter_is_valid이 (ITER, list_store 그때) 행을 액세스하고 나는 목록 또는 사용 treeselection unSelectAll을 (지우면 다음 열 값을 읽었다면 나는 오류를 얻을 ') G_VALUE_HOLDS_STRING (값

실패)'주장 : g_value_get_string

입심-G 객체-CRITICAL ** 실패 '를

코드는 여전히 작동하지만 오류는 마음에 들지 않습니다. 잘못된 행을 읽고있는 것처럼 느껴지지만 어떻게 볼 수는 없습니다. 내 코드 참조 : 맨 아래에 void fileForm :: on_treeview_selected(). 변수 "f"는 원래 "파일 이름"이었지만 버려야 할 변수조차도 iter에 문제가 있음을 증명하기 위해 변경했습니다. 폼은 Glade에서 빌드되었고 GTK :: Builder를 사용하여 참조되었습니다. 나는 것 같다 리눅스 민트 18.2`/*

/* 
* File: fileForm.h 
* Author: john 
* 
* Created on November 16, 2017, 6:26 PM 
*/ 

#ifndef FILEFORM_H 
#define FILEFORM_H 

#include <gtkmm/builder.h> 
#include <gtkmm/treeview.h> 
#include <gtkmm/liststore.h> 
#include <gtkmm/scrolledwindow.h> 
#include <gtkmm/scrollbar.h> 
#include <gtkmm/cellrendererprogress.h> 
#include <gtkmm/button.h> 
#include <gtkmm/buttonbox.h> 
#include <gtkmm/box.h> 
#include <gtkmm/label.h> 
#include <gtkmm/entry.h> 
#include <gtkmm/window.h> 
#include <gtkmm/scrolledwindow.h> 
#include <sstream> 
#include <dirent.h> 
#include <string> 
#include "generalClasses.h" 


//not using Glade as can't do List Store so pointless 

class fileForm : public Gtk::Window { 
public: 
    fileForm(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade); 
    fileForm(const fileForm& orig); 
    virtual ~fileForm(); 
    void show(std::string fileExtension = ""); 
    std::string filename = ""; 
protected: 
    Glib::RefPtr<Gtk::Builder> m_builder;  
    std::string m_fileExtension; 

    //Tree model columns: 
    class ModelColumns : public Gtk::TreeModel::ColumnRecord 
    { 
    public: 

     ModelColumns() 
     { add(m_col_id); add(m_col_name); add(m_col_date);} 

     Gtk::TreeModelColumn<unsigned int> m_col_id; 
     Gtk::TreeModelColumn<Glib::ustring> m_col_name; 
     Gtk::TreeModelColumn<Glib::ustring> m_col_date; 
    }; 

    ModelColumns m_columns; 

    //Child widgets: 
    Gtk::Button* m_topButton; 
    Gtk::Button* m_upButton; 
    Gtk::Button* m_downButton; 
    Gtk::Button* m_bottomButton; 

    Gtk::TreeView* m_treeView; 
    Gtk::ScrolledWindow* m_scrolledWindow; 
    Glib::RefPtr<Gtk::TreeSelection> m_treeSelection; 
    Glib::RefPtr<Gtk::ListStore> m_refTreeModel; 
// Gtk::ListStore* m_refTreeModel; 

    Gtk::Button* m_cancelButton; 
    Gtk::Button* m_loadButton; 
private: 
    //Signal handlers: 
    void on_loadButton_clicked(); 
    void on_cancelButton_clicked(); 
    void on_topButton_clicked(); 
    void on_upButton_clicked(); 
    void on_downButton_clicked(); 
    void on_bottomButton_clicked(); 
    void on_treeview_selected(); 

}; 

#endif /* FILEFORM_H */ 


/* 
* File: fileForm.cpp 
* Author: john 
* 
* Created on November 16, 2017, 6:26 PM 
*/ 

#include "fileForm.h" 

using namespace Glib; 
using namespace std; 


fileForm::fileForm(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) 
: Gtk::Window(cobject), 
    m_builder(refGlade) 
{ 
    set_title("Select file"); 

    m_builder->get_widget("topButton",m_topButton); 
    m_builder->get_widget("upButton",m_upButton); 
    m_builder->get_widget("downButton",m_downButton); 
    m_builder->get_widget("bottomButton",m_bottomButton); 

    m_builder->get_widget("cancelButton",m_cancelButton); 
    m_builder->get_widget("loadButton",m_loadButton); 

    m_builder->get_widget("treeview1",m_treeView); 
    m_builder->get_widget("scrolledwindow1", m_scrolledWindow); 

    m_refTreeModel = Gtk::ListStore::create(m_columns); 
    m_treeView->set_model(m_refTreeModel); 
    m_treeSelection = m_treeView->get_selection(); 
    //Add the TreeView's view columns: 
    //This number will be shown with the default numeric formatting. 
    m_treeView->append_column("ID", m_columns.m_col_id); 
    m_treeView->append_column("Name", m_columns.m_col_name); 
    m_treeView->append_column("Date",m_columns.m_col_date); 



    m_cancelButton->signal_clicked().connect(sigc::mem_fun(*this, &fileForm::on_cancelButton_clicked)); 
    m_loadButton->signal_clicked().connect(sigc::mem_fun(*this, &fileForm::on_loadButton_clicked)); 
    m_treeSelection->signal_changed().connect(sigc::mem_fun(*this, &fileForm::on_treeview_selected),false); 
} 

void fileForm::show(std::string fileExtension){ 

    //open file and list 
    int rowCount = 0; 
    char buffer[30]; 
    DIR *d; 
    struct dirent *dir; 
    struct stat fileAttrib; 
    string s; 
    int pointPos; 

    filename = ""; 
    m_treeSelection->unselect_all(); //fault occurs on this line if the row.get_value was used 
    m_refTreeModel->clear(); //fault occurs on this line if the row.get_value was used 

    d = opendir("."); 
    if (d) 
    { 
     while ((dir = readdir(d)) != NULL) 
     { 
      stat(dir->d_name, &fileAttrib); 
      s = dir->d_name; 
      pointPos = s.find("." + fileExtension); 
      s = s.substr(0,pointPos);   
      //Fill the TreeView's model 
      if ((s !=".") && (s !="..") && (s != "") && (pointPos > 0)) //show only files and no directories 
      { 
      Gtk::TreeModel::Row row = *(m_refTreeModel->append()); 
      row[m_columns.m_col_id] = ++rowCount; 
      row[m_columns.m_col_name] = s; 
      timespecToStr(buffer, &fileAttrib.st_mtim); 
      if (buffer != NULL) 
       row[m_columns.m_col_date] = buffer; 
      } 

     } 
    } 



    if (rowCount < 12)  //nasty but itll do for now 
    { 
    m_treeView->set_size_request(400,-1); 
    m_topButton->set_sensitive(false); 
    m_upButton->set_sensitive(false); 
    m_downButton->set_sensitive(false); 
    m_bottomButton->set_sensitive(false); 
    } 
    else  
    { 
    m_treeView->set_size_request(400,400); 
    m_topButton->set_sensitive(true); 
    m_upButton->set_sensitive(true); 
    m_downButton->set_sensitive(true); 
    m_bottomButton->set_sensitive(true); 
    } 


    //Make all the columns reorderable: 
    //This is not necessary, but it's nice to show the feature. 
    //You can use TreeView::set_column_drag_function() to more 
    //finely control column drag and drop. 
    /* 
    for(guint i = 0; i < 3; i++) 
    { 
    auto column = m_treeView->get_column(i); 
    column->set_reorderable(); 
    } 
    */ 
    m_loadButton->set_sensitive(false); //disabled until a selection is made 
    m_cancelButton->grab_focus(); 

    Gtk::Window::show_all(); 
} 


void fileForm::on_loadButton_clicked() 
{ 
    //filename selected when tree selected 
    filename += "." + m_fileExtension; 
    hide(); 
} 

void fileForm::on_cancelButton_clicked() 
{ 
    filename = ""; 
    hide(); 
} 

void fileForm::on_treeview_selected() 
{ 
    ustring f = ""; 
    m_loadButton->set_sensitive(true); //disabled until a selection is made 

    Gtk::TreeIter treeiter = m_treeSelection->get_selected(); 
    Gtk::TreeModel::Row row = *treeiter; 
    f = row.get_value(m_columns.m_col_name); //not using f this is just to test, fault still occurs 
    //removing the row above stops the error occuring 


} 

답변

0

이 잘 그것은 나에게 동안을했다하지만 treeiter이

`void fileForm::on_treeview_selected() 
{ 

    Gtk::TreeIter treeiter = m_treeSelection->get_selected(); 
    if (treeiter) { 
    Gtk::TreeModel::Row row = *treeiter; 
    m_filename = row.get_value(m_columns.m_col_name); 
    } 

}` 

유효 만약 내가보고 확인하여 메시지를 없애있어 사용하고있어 on_treeView_selected()는 오류를 일으키는 유효한 선택없이 호출되어야합니다.

관련 문제