首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Gtkmm3 TreeView ListStore.Clear或TreeSelection.unselectAll导致错误

Gtkmm3 TreeView ListStore.Clear或TreeSelection.unselectAll导致错误
EN

Stack Overflow用户
提问于 2017-11-26 14:49:57
回答 1查看 454关注 0票数 1

我试图使用TreeView列出目录的内容,然后在列表中选择文件名。我不想使用文件选择器对话框,因为我想限制用户对一个目录的访问,不希望他们在系统中导航。我的代码可以正常工作,直到我想清除列表并更新它。如果我访问了一行并读取了列值,那么当我清除列表或使用树选择unSelectAll()时,就会得到以下错误:

gtk_list_store_get_value:断言'iter_is_valid (iter,list_store)‘失败

g_value_get_string:断言'G_VALUE_HOLDS_STRING (值)‘失败

代码仍然有效,但我不喜欢这些错误。感觉好像我看错了这一行,但我看不出是怎么回事。请参阅我的代码:最底层的fileForm::on_treeview_selected() 。变量"f“最初是”文件名“,但我对其进行了更改,以证明即使是应该丢弃的变量也会导致iter出现问题。该表单是在Glade中构建的,并使用GTK::Builder引用。我使用的是Linux 18.2‘/*

代码语言:javascript
复制
/* 
 * 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


}
EN

回答 1

Stack Overflow用户

发布于 2018-01-29 20:26:45

嗯,这花了我一段时间,但我通过检查树符是否有效来消除这些信息。

代码语言:javascript
复制
`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()必须在没有导致错误的有效选择的情况下被调用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47497378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档