问题描述
为了了解上下文,我正在制作一个 GUI 应用程序,该应用程序基于通过 GtkEntry(如 ls
)的输入命令,它会弹出一个窗口,其中包含该目录中的相应文件。所以 GTK4 演示有一个文件浏览器的例子,可以完美地满足我的需求,但我无法让它工作!
这是我的项目结构:
main.c
#include <gtk/gtk.h>
#include "../headers/mainApp.h"
int main(int argc,char* argv[]){
g_setenv("GSETTINGS_SCHEMA_DIR",".",FALSE);
return g_application_run(G_APPLICATION(main_app_new()),argc,argv);
}
mainApp.c
#include <gtk/gtk.h>
#include "../headers/mainApp.h"
#include "../headers/mainAppWindow.h"
#include "../headers/mainAppPreferences.h"
static void main_app_init(MainApP* app);
static void main_app_class_init(MainAppClass* class);
static void main_app_open(GApplication* app,GFile** files,int n_files,const char* hint);
static void preferences_activated(GSimpleAction* action,GVariant* parameter,gpointer app);
static void quit_activated(GSimpleAction* action,gpointer app);
static void main_app_startup(GApplication* app);
static void main_app_activate(GApplication* app);
struct _MainApp {
GtkApplication parent;
};
G_DEFINE_TYPE(MainApp,main_app,GTK_TYPE_APPLICATION)
MainApP* main_app_new(void) {
return g_object_new(MAIN_APP_TYPE,"application-id","org.gtk.mainapp","flags",G_APPLICATION_HANDLES_OPEN,NULL);
}
static void main_app_init(MainApP* app){}
static void main_app_open(GApplication* app,const char* hint){
GList* windows;
MainAppWindow* window;
int i;
windows = gtk_application_get_windows(GTK_APPLICATION(app));
if(windows)
window = MAIN_APP_WINDOW(MAIN_APP(app));
else
window = main_app_window_new(MAIN_APP(app));
/*for(i = 0; i < n_files; i++)
main_app_window_open(window,files[i]);*/
gtk_window_present(GTK_WINDOW(window));
}
static void main_app_class_init(MainAppClass* class){
G_APPLICATION_CLASS (class)->startup = main_app_startup;
G_APPLICATION_CLASS (class)->activate = main_app_activate;
G_APPLICATION_CLASS (class)->open = main_app_open;
}
static void preferences_activated(GSimpleAction* action,gpointer app){
MainAppPreferences *preferences;
GtkWindow *window;
window = gtk_application_get_active_window (GTK_APPLICATION (app));
preferences = main_app_preferences_new(MAIN_APP_WINDOW(window));
gtk_window_present (GTK_WINDOW (preferences));
}
static void quit_activated(GSimpleAction* action,gpointer app){
g_application_quit (G_APPLICATION (app));
}
static GActionEntry app_entries[] = {
{ "preferences",preferences_activated,NULL,NULL },{ "quit",quit_activated,NULL }
};
static void main_app_startup(GApplication* app){
const char* quit_accels[2] = {"<Ctrl>Q",NULL};
G_APPLICATION_CLASS(main_app_parent_class)->startup (app);
g_action_map_add_action_entries (G_ACTION_MAP (app),app_entries,G_N_ELEMENTS (app_entries),app);
gtk_application_set_accels_for_action (GTK_APPLICATION (app),"app.quit",quit_accels);
}
static void main_app_activate(GApplication* app){
MainAppWindow* window;
window = main_app_window_new(MAIN_APP(app));
gtk_window_present(GTK_WINDOW(window));
}
mainAppWindow.c
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include <stdio.h>
#include "../headers/mainApp.h"
#include "../headers/mainAppWindow.h"
#include "../headers/filebrowserView.h"
static void main_app_window_class_init(MainAppWindowClass* class);
static void main_app_window_dispose(GObject* object);
static void main_app_window_init(MainAppWindow* window);
static void command_changed(GtkEntry* entry,MainAppWindow* window);
static void command_submit_pressed(gtkbutton *button,gpointer user_data);
static GtkTreeModel* create_completion_model(void);
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
struct _MainAppWindow {
Gtkapplicationwindow parent;
GSettings* settings;
GtkWidget* gears;
GtkWidget* commandEntry;
GtkWidget* btnCommandSubmit;
GtkWidget* stack;
};
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
G_DEFINE_TYPE (MainAppWindow,main_app_window,GTK_TYPE_APPLICATION_WINDOW)
MainAppWindow* main_app_window_new(MainApP* app){
return g_object_new(MAIN_APP_WINDOW_TYPE,"application",app,NULL);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void main_app_window_class_init(MainAppWindowClass* class){
GObjectClass* gobject_class = G_OBJECT_CLASS(class);
gobject_class->dispose = main_app_window_dispose;
gtk_widget_class_set_template_from_resource(GTK_WIDGET_CLASS(class),"/org/gtk/mainapp/ui/window.ui");
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),MainAppWindow,gears);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),commandEntry);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),btnCommandSubmit);
gtk_widget_class_bind_template_child (GTK_WIDGET_CLASS (class),stack);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),command_changed);
gtk_widget_class_bind_template_callback (GTK_WIDGET_CLASS (class),command_submit_pressed);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void main_app_window_init(MainAppWindow* window){
GtkBuilder* builder;
GMenuModel* menu;
GAction* action;
GtkEntryCompletion* completion;
GtkTreeModel *completion_model;
GtkBox* Box;
gtk_widget_init_template(GTK_WIDGET(window));
builder = gtk_builder_new_from_resource("/org/gtk/mainapp/ui/gears-menu.ui");
menu = G_MENU_MODEL(gtk_builder_get_object(builder,"menu"));
gtk_menu_button_set_menu_model(GTK_MENU_BUTTON(window->gears),menu);
window->stack = GTK_WIDGET(gtk_builder_get_object(builder,"stack"));
g_object_unref(builder);
window->settings = g_settings_new("org.gtk.mainapp");
//Create completion object.
completion = gtk_entry_completion_new();
//Asign the completion to the entry.
gtk_entry_set_completion(GTK_ENTRY(window->commandEntry),completion);
g_object_unref(completion);
//Create a tree model and use it as the completion model.
completion_model = create_completion_model();
gtk_entry_completion_set_model(completion,completion_model);
g_object_unref(completion_model);
/* Use model column 0 as the text column */
gtk_entry_completion_set_text_column (completion,0);
gtk_entry_completion_set_inline_completion (completion,TRUE);
gtk_entry_completion_set_inline_selection (completion,TRUE);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
void main_app_window_open(MainAppWindow* window,GFile* file){
char *basename;
GtkWidget *scrolled,*view;
char *contents;
gsize length;
GtkTextBuffer *buffer;
GtkTextTag *tag;
GtkTextIter start_iter,end_iter;
basename = g_file_get_basename (file);
scrolled = gtk_scrolled_window_new ();
gtk_widget_set_hexpand (scrolled,TRUE);
gtk_widget_set_vexpand (scrolled,TRUE);
view = gtk_text_view_new ();
gtk_text_view_set_editable (GTK_TEXT_VIEW (view),FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (view),FALSE);
gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled),view);
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
if (g_file_load_contents (file,&contents,&length,NULL))
{
gtk_text_buffer_set_text (buffer,contents,length);
g_free (contents);
}
tag = gtk_text_buffer_create_tag (buffer,NULL);
g_settings_bind (window->settings,"font",tag,G_SETTINGS_BIND_DEFAULT);
gtk_text_buffer_get_start_iter (buffer,&start_iter);
gtk_text_buffer_get_end_iter (buffer,&end_iter);
gtk_text_buffer_apply_tag (buffer,&start_iter,&end_iter);
g_free (basename);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void main_app_window_dispose(GObject* object){
MainAppWindow* window;
window = MAIN_APP_WINDOW(object);
g_clear_object(&window->settings);
G_OBJECT_CLASS(main_app_window_parent_class)->dispose(object);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void command_changed(GtkEntry* entry,MainAppWindow* window){
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void command_submit_pressed(gtkbutton *button,gpointer user_data){
GtkWidget* window;
window = do_listview_filebrowser(NULL);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static GtkTreeModel* create_completion_model(void){
const char* commands[] = {
"ls [dir]","ls -l [dir]","cat [file_path]","pwd","adduser [user_name]","deluser [user_name]",NULL
};
int i;
GtkListStore *store;
GtkTreeIter iter;
store = gtk_list_store_new (1,G_TYPE_STRING);
for (i = 0; commands[i]; i++)
{
/* Append one word */
gtk_list_store_append (store,&iter);
gtk_list_store_set (store,&iter,commands[i],-1);
}
return GTK_TREE_MODEL (store);
}
///////////////////////////////////////////////////////////////////////////////////////
/* Layout:
+-------------------------------------+
| +-----------++-------++-----------+ |
| | CmdEntry || Space || Submit | |
| +-----------++-------++-----------+ |
+-------------------------------------+
Constraints:
super.start = cmdEntry.start - 8
cmdEntry.end = space.start
space.end = Submit.start
submit.end = super.end - 8
*/
///////////////////////////////////////////////////////////////////////////////////////
filebrowserView.c
#include <gtk/gtk.h>
#include <glib/gi18n.h>
#include "../headers/mainAppWindow.h"
#include "../headers/filebrowserView.h"
static void file_browser_view_set_property (GObject* object,guint prop_id,const GValue* value,GParamSpec* pspec);
static void file_browser_view_get_property (GObject* object,guint property_id,GValue* value,GParamSpec* pspec);
static void file_browser_view_finalize (GObject *object);
char* filebrowser_get_display_name (GObject* object,GFileInfo* info);
char* filebrowser_get_content_type (GObject* object,GFileInfo* info);
char* filebrowser_get_size (GObject* object,GFileInfo* info);
GIcon* filebrowser_get_icon (GObject* object,GFileInfo* info);
void filebrowser_up_clicked_cb (gtkbutton* button,GtkDirectoryList* list);
void filebrowser_view_activated_cb (GtkGridView* view,guint pos,GtkDirectoryList* list);
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
struct _FilebrowserView {
GObject parent_instance;
GtkListItemFactory *factory;
char *icon_name;
char *title;
GtkOrientation orientation;
};
enum {
PROP_0,PROP_FACTORY,PROP_ICON_NAME,PROP_TITLE,PROP_ORIENTATION,N_PROPS
};
static GParamSpec* properties[N_PROPS] = { NULL,};
static GtkWidget *window = NULL;
G_DEFINE_TYPE (FilebrowserView,file_browser_view,G_TYPE_OBJECT)
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
FilebrowserView* file_browser_view_new(GtkWindow* window){
return g_object_new(FILE_broWSER_TYPE,window,NULL);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void file_browser_view_class_init(FilebrowserViewClass* view){
GObjectClass* gobject_class = G_OBJECT_CLASS(view);
gobject_class->get_property = file_browser_view_get_property;
gobject_class->set_property = file_browser_view_set_property;
gobject_class->finalize = file_browser_view_finalize;
properties[PROP_FACTORY] =
g_param_spec_object ("factory","factory","factory to use in the main view",GTK_TYPE_LIST_ITEM_FACTORY,G_ParaM_READWRITE);
properties[PROP_ICON_NAME] =
g_param_spec_string ("icon-name","icon name","icon to display for selecting this view",G_ParaM_READWRITE);
properties[PROP_TITLE] =
g_param_spec_string ("title","title","title to display for selecting this view",G_ParaM_READWRITE);
properties[PROP_ORIENTATION] =
g_param_spec_enum ("orientation","orientation","orientation of the view",GTK_TYPE_ORIENTATION,GTK_ORIENTATION_VERTICAL,G_ParaM_READWRITE);
g_object_class_install_properties (gobject_class,N_PROPS,properties);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void file_browser_view_init(FilebrowserView* view) {}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void file_browser_view_get_property (GObject* object,GParamSpec* pspec) {
FilebrowserView *self = FILE_broWSER_VIEW (object);
switch (property_id) {
case PROP_FACTORY:
g_value_set_object (value,self->factory);
break;
case PROP_ICON_NAME:
g_value_set_string (value,self->icon_name);
break;
case PROP_TITLE:
g_value_set_string (value,self->title);
break;
case PROP_ORIENTATION:
g_value_set_enum (value,self->orientation);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object,property_id,pspec);
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void file_browser_view_set_property (GObject* object,GParamSpec* pspec) {
FilebrowserView *self = FILE_broWSER_VIEW (object);
switch (prop_id) {
case PROP_FACTORY:
g_set_object (&self->factory,g_value_get_object (value));
break;
case PROP_ICON_NAME:
g_free (self->icon_name);
self->icon_name = g_value_dup_string (value);
break;
case PROP_TITLE:
g_free (self->title);
self->title = g_value_dup_string (value);
break;
case PROP_ORIENTATION:
self->orientation = g_value_get_enum (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object,prop_id,pspec);
break;
}
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
static void file_browser_view_finalize (GObject *object) {
FilebrowserView *self = FILE_broWSER_VIEW (object);
g_object_unref (self->factory);
g_free (self->icon_name);
g_free (self->title);
G_OBJECT_CLASS (file_browser_view_parent_class)->dispose (object);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
char* filebrowser_get_display_name (GObject* object,GFileInfo* info) {
if (!info)
return NULL;
return g_strdup (g_file_info_get_attribute_string (info,"standard::display-name"));
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
char* filebrowser_get_content_type (GObject* object,"standard::content-type"));
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
char* filebrowser_get_size (GObject* object,GFileInfo* info) {
if (!info)
return NULL;
return g_format_size (g_file_info_get_attribute_uint64 (info,"standard::size"));
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
GIcon* filebrowser_get_icon (GObject* object,GFileInfo* info) {
GIcon *icon;
if (info)
icon = G_ICON (g_file_info_get_attribute_object (info,"standard::icon"));
else
icon = NULL;
if (icon)
g_object_ref (icon);
return icon;
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
void filebrowser_up_clicked_cb (gtkbutton* button,GtkDirectoryList* list) {
GFile *file;
file = g_file_get_parent (gtk_directory_list_get_file (list));
if (file == NULL)
return;
gtk_directory_list_set_file (list,file);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
void filebrowser_view_activated_cb (GtkGridView* view,GtkDirectoryList* list) {
GFileInfo *info;
info = g_list_model_get_item (G_LIST_MODEL (gtk_grid_view_get_model (view)),pos);
if (g_file_info_get_file_type (info) == G_FILE_TYPE_DIRECTORY)
gtk_directory_list_set_file (list,G_FILE (g_file_info_get_attribute_object (info,"standard::file")));
g_object_unref (info);
}
///////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////
GtkWidget* do_listview_filebrowser (GtkWidget *do_widget) {
if (!window)
{
GtkWidget *view;
GtkBuilder *builder;
GtkDirectoryList *dirlist;
GFile *file;
char *cwd;
GtkCssprovider *provider;
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_resource (provider,"/org/gtk/mainapp/css/filebrowser.css");
gtk_style_context_add_provider_for_display (gdk_display_get_default (),GTK_STYLE_PROVIDER (provider),800);
g_object_unref (provider);
builder = gtk_builder_new_from_resource ("/org/gtk/mainapp/ui/file-browser.ui");
window = GTK_WIDGET (gtk_builder_get_object (builder,"window"));
g_signal_connect(window,"clicked",G_CALLBACK(filebrowser_up_clicked_cb),NULL);
g_signal_connect(window,"activate",G_CALLBACK(filebrowser_view_activated_cb),NULL);
gtk_window_set_display (GTK_WINDOW (window),gtk_widget_get_display (do_widget));
g_object_add_weak_pointer (G_OBJECT (window),(gpointer *) &window);
/* Create the model and fill it with the contents of the current directory */
cwd = g_get_current_dir ();
file = g_file_new_for_path (cwd);
g_free (cwd);
dirlist = GTK_DIRECTORY_LIST (gtk_builder_get_object (builder,"dirlist"));
gtk_directory_list_set_file (dirlist,file);
g_object_unref (file);
/* grab focus in the view */
view = GTK_WIDGET (gtk_builder_get_object (builder,"view"));
gtk_widget_grab_focus (view);
g_object_unref (builder);
}
if (!gtk_widget_get_visible (window))
gtk_widget_show (window);
else
gtk_window_destroy (GTK_WINDOW (window));
return window;
}
file-browser.ui
https://github.com/panchis7u7/Encryption_Algorithms/blob/master/GUI_User_Resource_Manager/ui/file-browser.ui
如果我尝试运行代码,我会得到一个 Failed to add UI from resource /org/gtk/mainapp/ui/file-browser.ui: .:66:1 Invalid type 'FilebrowserView'
作为一种解决方案,我只是通过 file_browser_view_new()
方法调用该方法来创建一个新的 FilebrowserView 并起作用,但是 file-browser.ui
中的信号未位于:Failed to add UI from resource /org/gtk/mainapp/ui/file-browser.ui: No function named filebrowser_up_clicked_cb.
更多细节,这里是github中的项目:https://github.com/panchis7u7/Encryption_Algorithms/tree/master/GUI_User_Resource_Manager
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)