Hello,
I want rewrite my old app (gtk2) to gtk4 (written in C).
I am using there function
GtkWidget* FindChild(GtkWidget* parent, const gchar* name) { … }
which I have before many years found at:
for gtk2 it works fine but for gtk4 it is neccesary update it…
It should explore a GTK GUI’s structure programmatically and return widget with entered name.
I can see in output log that correct widget is found but during returning from recursive function it is rewriten to NULL.
Pleace could anybody help how to improve my function to work.
I have prepared simple gui app to test it. You can enter searched name to entry to test it (e.g. “vert1”, “vert2”, “hor1” ect.)
Thank you a lot
#include <gtk/gtk.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <ctime>
#include <vector>
using namespace std;
GtkWidget* gVysledekHledani = NULL;
GtkWidget* entry;
//vrati vektor sourozencu
vector<GtkWidget*> GetWidgetSiblings (GtkWidget* widget) {
cout << "siblings for: " << gtk_widget_get_name(widget) << endl;
vector<GtkWidget*> tmpVektorSiblings;
tmpVektorSiblings.push_back(widget);
GtkWidget* nextSiblingWidget = gtk_widget_get_next_sibling(widget);
string jmeno;
do {
if (nextSiblingWidget != NULL ) {
jmeno = gtk_widget_get_name(nextSiblingWidget);
if (g_ascii_strcasecmp(jmeno.c_str(), "GtkTooltipWindow") == 0) {
cout << "skipping GtkTooltipWindow" << endl;
} else if (g_ascii_strcasecmp(jmeno.c_str(), "GtkHeaderBar") == 0) {
cout << "skipping GtkHeaderBar" << endl;
} else {
tmpVektorSiblings.push_back(nextSiblingWidget);
cout << "added to vektor: " << jmeno << "; vektor size:" << tmpVektorSiblings.size() << endl;
}
}
nextSiblingWidget = gtk_widget_get_next_sibling(nextSiblingWidget);
} while (nextSiblingWidget != NULL);
cout << "searching siblings finished! count="<< tmpVektorSiblings.size() << endl;
return tmpVektorSiblings;
}
GtkWidget* FindChild(GtkWidget* parent, const gchar* name) {
//najde a vrati ukazatel na pojmenovaneho potomka widgetu
cout << "findChild - we are looking for:" << name << endl;
if (GTK_IS_WIDGET(parent)) {
string jmenoRodice = gtk_widget_get_name(parent);
cout << "parrent name: " << jmenoRodice << endl;
if (g_ascii_strcasecmp(gtk_widget_get_name(parent), name) == 0) {
cout << "parrent is the SEARCHED widget !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
return parent;
}
vector<GtkWidget*> tmpVektorSourozencu = GetWidgetSiblings (parent);
GtkWidget* sourozenec;
GtkWidget* potomek;
string sourozenecJmeno;
for (unsigned int cnt = 0; cnt < tmpVektorSourozencu.size(); ++cnt) {
sourozenec = tmpVektorSourozencu.at(cnt);
sourozenecJmeno = gtk_widget_get_name(sourozenec);
cout << cnt << "(" << tmpVektorSourozencu.size() << "): testing " << sourozenecJmeno << endl;
potomek = gtk_widget_get_first_child(sourozenec);
if (potomek != NULL) {
cout << sourozenecJmeno << " has child - using recursion" << endl;
FindChild(potomek, name);
} else {
cout << sourozenecJmeno << " is without child" << endl;
if (g_ascii_strcasecmp(sourozenecJmeno.c_str(), name) == 0) {
cout << "sibling is SEARCHED widget !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
return sourozenec;
}
}
}
cout << "finishing with: " << jmenoRodice << endl;
}
cout << "finishing proc" << endl;
return NULL;
}
void NecoUdelej (GtkWidget* wid, GtkWidget* data) {
cout << endl << endl <<endl <<endl << "called function"<< endl;
string hledaneJmeno = gtk_editable_get_text(GTK_EDITABLE(entry));
cout << "i have read from enty name: " << hledaneJmeno << endl;
GtkWidget* widget = FindChild(wid, hledaneJmeno.c_str());
//GtkWidget* widget = FindChild(wid, "vert1");
if (widget != NULL) {
cout << "name of returned widget: " << gtk_widget_get_name(widget) << endl;
} else {
cout << "find child returned NULL" << endl;
}
}
static void appActivate (GApplication *app, gpointer user_data) {
GtkWidget *win = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_title (GTK_WINDOW (win), "Test");
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
gtk_widget_set_name(win,"hlavni okno apky");
GtkWidget *vBox = gtk_box_new (GTK_ORIENTATION_VERTICAL,10);
gtk_widget_set_name(vBox,"kontak vbox");
gtk_widget_set_margin_start(GTK_WIDGET(vBox),10);
gtk_widget_set_margin_bottom(GTK_WIDGET(vBox),10);
gtk_widget_set_margin_top(GTK_WIDGET(vBox),10);
gtk_widget_set_margin_end(GTK_WIDGET(vBox),10);
gtk_window_set_child (GTK_WINDOW (win), vBox);
GtkWidget *labText;
vector<string> vektorTextu;
vektorTextu.push_back("pokus 1");
vektorTextu.push_back("pokus 2");
vektorTextu.push_back("pokus 3");
vektorTextu.push_back("pokus 4");
vektorTextu.push_back("pokus 5");
string jmeno="";
if (vektorTextu.size() > 0) {
labText = gtk_label_new("");
gtk_label_set_markup(GTK_LABEL(labText), "<b>nadpis:</b>");
gtk_box_append (GTK_BOX (vBox), labText);
GtkWidget *hBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL,10);
gtk_widget_set_name(hBox,"kontak hbox");
for (int i = 0; i < vektorTextu.size(); ++i) {
labText = gtk_label_new(vektorTextu.at(i).c_str());
gtk_box_append (GTK_BOX (hBox), labText);
jmeno = "hor" + to_string(i);
gtk_widget_set_name(labText,jmeno.c_str());
}
gtk_box_append (GTK_BOX (vBox), hBox);
for (int i = 0; i < vektorTextu.size(); ++i) {
labText = gtk_label_new(vektorTextu.at(i).c_str());
gtk_box_append (GTK_BOX (vBox), labText);
jmeno = "vert" + to_string(i);
gtk_widget_set_name(labText,jmeno.c_str());
}
} else {
labText = gtk_label_new("vektor je prazdnej");
gtk_box_append (GTK_BOX (vBox), labText);
}
labText = gtk_label_new("");
gtk_box_append (GTK_BOX (vBox), labText);
entry = gtk_entry_new ();
gtk_box_append (GTK_BOX (vBox), entry);
gtk_widget_set_name(entry,"entry");
g_object_set_data(G_OBJECT(win), "entry",entry);
GtkWidget *btnNeco = gtk_button_new_with_label("find widget with entered name");
gtk_box_append (GTK_BOX (vBox), btnNeco);
g_signal_connect_swapped(GTK_BUTTON(btnNeco), "clicked", G_CALLBACK(NecoUdelej), win);
GtkWidget *btnBack = gtk_button_new_with_label("Close");
gtk_box_append (GTK_BOX (vBox), btnBack);
g_signal_connect_swapped(GTK_BUTTON(btnBack), "clicked", G_CALLBACK(gtk_window_destroy), win);
gtk_widget_show (win);
}
int main(int argc, char **argv) {
GtkApplication *app;
app = gtk_application_new ("testing.app", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (appActivate), NULL);
return g_application_run (G_APPLICATION (app), NULL, NULL);
g_object_unref (app);
return 0;
}