C Programm funktioniert nicht Richtig?
Es geht um folgenden Code:
#include <gtk/gtk.h>
#include <string.h>
// Globale Variablen für die UI-Elemente
GtkWidget *search_entry;
GtkWidget *treeview;
GtkListStore *list_store;
GtkTreeModel *filter_model;
// Beispiel-Lagerbestand
typedef struct {
const gchar *artikelnummer;
const gchar *name;
int bestand;
} Lagerartikel;
// Beispielhafte Lagerartikel
Lagerartikel lager[] = {
{"1001", "Laptop", 15},
{"1002", "Maus", 50},
{"1003", "Tastatur", 30},
{"1004", "Monitor", 10},
{"1005", "Drucker", 5},
{"1006", "USB-Stick", 100}
};
const int lager_size = sizeof(lager) / sizeof(lager[0]);
// Filterfunktion für die Suche
static gboolean filter_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer data) {
gchar *artikelnummer = NULL;
gtk_tree_model_get(model, iter, 0, &artikelnummer, -1);
if (artikelnummer == NULL) {
return TRUE;
}
GtkWidget *search_entry = GTK_WIDGET(data);
const gchar *search_text = gtk_entry_get_text(GTK_ENTRY(search_entry));
if (search_text == NULL) {
search_text = "";
}
gboolean visible = TRUE;
if (strlen(search_text) > 0) {
visible = g_strrstr(artikelnummer, search_text) != NULL;
}
g_free(artikelnummer);
return visible;
}
// Aktualisiert den Filter, wenn sich der Suchtext ändert
static void on_search_changed(GtkSearchEntry *entry, gpointer user_data) {
gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(filter_model));
}
// Erstellt die Lagerbestand-Tabelle
static void setup_treeview(GtkBuilder *builder) {
treeview = GTK_WIDGET(gtk_builder_get_object(builder, "treeview"));
// Spalten für die TreeView erstellen
GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
GtkTreeViewColumn *col1 = gtk_tree_view_column_new_with_attributes("Artikelnummer", renderer, "text", 0, NULL);
GtkTreeViewColumn *col2 = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", 1, NULL);
GtkTreeViewColumn *col3 = gtk_tree_view_column_new_with_attributes("Bestand", renderer, "text", 2, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col1);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col2);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col3);
// ListStore erstellen und Daten füllen
list_store = gtk_list_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT);
for (int i = 0; i < lager_size; i++) {
GtkTreeIter iter;
gtk_list_store_append(list_store, &iter);
gtk_list_store_set(list_store, &iter, 0, lager[i].artikelnummer, 1, lager[i].name, 2, lager[i].bestand, -1);
}
// Filtermodell erstellen
filter_model = gtk_tree_model_filter_new(GTK_TREE_MODEL(list_store), NULL);
gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(filter_model), filter_func, search_entry, NULL);
gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), filter_model);
}
// Hauptfunktion
int main(int argc, char *argv[]) {
gtk_init(&argc, &argv);
// Glade-Datei laden
GtkBuilder *builder = gtk_builder_new_from_file("part1.glade");
// Widgets abrufen
GtkWidget *window = GTK_WIDGET(gtk_builder_get_object(builder, "main_window"));
search_entry = GTK_WIDGET(gtk_builder_get_object(builder, "search_entry"));
// Signal für die Suche
g_signal_connect(search_entry, "search-changed", G_CALLBACK(on_search_changed), search_entry);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
// Setup für die TreeView
setup_treeview(builder);
// Fenster anzeigen
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Ich benutze Glade um mit c ein interface zu erstelle.
Hier sollen die definierten Lagerartikel nach den Artikelnummern gesucht werden. Wenn man etwa 1002 eingibt bleibt nur 1002 übrig. wenn ich jetzt aber die 2 wegnehme, bleibt nur 1002 und 1003 übrig, obwohl alle angezeigt werden sollten.
Jetzt ist meine Frage, wie ich das beheben kann.
Auch ist folgendes: Bei 1003 zu 100 kommt 1003, 1004, 1005. Bei 1004 zu 100 kommt 1004, 1005, 1006, genau das gleiche bei 1005 und 1006. Nur bei 1001 zu 100 kommt alles
Liege ich mit meiner Einschätzung richtig, dass hier ein wenig ChatGPT oder Ähnliches im Einsatz gewesen sind?
Das stimmt, ganz so gut kenne ich mich noch nicht aus. Ich kann Code relativ gut lesen, aber noch nicht gut schreiben, da ich mich erst mit den Möglichkeiten vertraut machen muss.
3 Antworten
Offenbar wird on_search_changed() nicht oder zum falschen Zeitpunkt aufgerufen. Dann wird die Suche bei jeder Änderung nur eingeschränkt.
Hast Du in Glade wirklich ein Gtk.SearchEntry (mit find- und clear-Button) angelegt?Wenn ja, bau mal eine Ausgabe des Suchtextes in on_search_changed() ein. Erscheint da immer der aktuelle Suchtext?
Dann zeig mal Deine "part1.glade", damit ich (oder jemand anderes) es ausprobieren kann.
Welche gtk-Version verwendest Du?
Ich verwende die glade Version 3.40.0. Leider kann ich die Datei hier nicht einfügen, und der Code ist zu lang, falls du mir sagen könntest, wie ich es weiterleiten kann, wäre ich sehr dankbar.
Zu lang, bei 3 Objekten??? Dann bastle ich mir lieber selber etwas -- aber erst am Wochenende.
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow" id="main_window">
<property name="can-focus">False</property>
<child>
<object class="GtkBox" id="Box">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="activates-default">True</property>
<property name="primary-icon-name">edit-find-symbolic</property>
<property name="primary-icon-activatable">False</property>
<property name="primary-icon-sensitive">False</property>
<property name="input-purpose">digits</property>
<signal name="search-changed" handler="on_search_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTreeView" id="treeview">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="headers-clickable">False</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
</interface>
ah, ich hatte es oben probiert, da können nur 5000 zeichen sein, aber als kommentar geht anscheinend mehr, tut mir leid.
Ich kann dein Problem jetzt nachvollziehen, habe aber noch keine Erklärung dafür.
Auffällig ist, dass nach einem Backspace jede Zeile zweimal verglichen wird. Entweder ist der Iterator kaputt, oder der Filter läuft zweimal gleichzeitig.
Oder was komplett anderes :-/
Also gibt es eher nicht viel was ich tun kann? :-/
AUTSCH! Gib mal 0 2 Backspace ein. Dann siehst Du nur die Zeilen 1002 und 1003 (statt alle). Und jetzt klick in die Tabelle und drück ein paar mal Pfeil-rauf und -runter ... voilà, es ist alles da!
Sprich: Es funktioniert alles, aber Du hast im .gradle expand=False gesetzt (Zeile 36). Der Filter verkleinert die Tabelle automatisch, macht sie aber nur größer, wenn sie 0 Zeilen anzeigt.
Am besten packst Du die TreeView in Gradle in ein ScrolledWindow.
das mit dem scrolledWindow hat perfekt geholfen. Da fühl ich mich fast schon schlecht, weil ich deine Zeit so verschwendet habe. Vielen vielen dank.
Sofern du jetzt nicht extreme.Performance benötigst verwende zum Suchen einen Regex. Die sind flexibler.
Für die Aufgabe die du willst brauchst du aber auch einfach nur zu prüfen ob der String mit der Nummer beginnt.
Also 1002 1003 1004 usw beginnen eben alle mit 100 dazu musst du nicht nur prüfen dass 100 drinnen vorkommt sondern dieser Substring am Anfang steht.
Also kein Vergleich auf ungleich 0 sondern strstr (str1,str2) == str1
Versuch doch mal nen eigenen Code zu schreiben. Mit ChatGPT lernst du nichts und stellst dir selbst nur ein Bein. Du verstehst den Code nicht weil du ihn nicht geschrieben hast. Und genau an diesem Punkt solltest du arbeiten.
Jap, das SeachEntry habe ich, es wird an sich auch alles angezeigt. ich habe noch einige Tests gemacht. Es kommen sowohl die richtigen gboolean Werte bei der filter_func raus, als auch wird der richtige Suchtext sowohl in der filter_func, als auch in der on_search_changed() funktion angezeigt. Allein vom output her müsste es eigentlich funktionieren.