GTKMM Gtk::TextBuffer nutzen beim Multithreading
-
Hallo allerseits, ich bin neu in dem Forum und hoffe auch Hilfe zu finden.
Sollten Bemerkungen oder sonstiges sein nur sagen.Da ich nicht viel drum herum reden will komme ich gleich zum Thema.
Schreibe eine Grafische Oberfläche mit GTKmmMein vorhaben ist ein vernünftiges grafisches Terminal-Programm zu schreiben.
In dem Terminal-Programm soll möglich sein mit einem µC (Microcontroller) über die RS232 Schnittstelle zu kommunizieren.
Empfangene Daten sollen angezeigt werden.
Damit mein Programm bei der Schnittstellen Kommunikation nicht einfriert nutzte ich Threads in GTKmm.
Mein Problem ist mit dem Gtk::TextView genauer gesagt Gtk::Buffer.
Wenn ich einen Thread laufen lasse der in den Buffer Daten reinschreibt geht das nur mit einer begrenzten Geschwindigkeit wird es zu schnell stürzt das Programm ab, hier die Fehlermeldung:(gtk_programm:7286): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
(gtk_programm:7286): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
(gtk_programm:7286): Gtk-CRITICAL **: gtk_text_layout_real_invalidate: assertion `layout->wrap_loop_count == 0' failed
(gtk_programm:7286): Gtk-WARNING **: Invalid text buffer iterator: either the iterator is uninitialized, or the characters/pixbufs/widgets in the buffer have been modified since the iterator was created.
You must use marks, character numbers, or line numbers to preserve a position across buffer modifications.
You can apply tags and insert marks without invalidating your iterators,
but any mutation that affects 'indexable' buffer contents (contents that can be referred to by character offset)
will invalidate all outstanding iteratorsWas könnte das sein bzw. wie kann ich das umgehen?
Da über die RS232 Schnittstelle die Daten schnell rein kommen können möchte ich das nicht über den Hauptthread laufen lassen da das Programm dann
einfrieren würde.Bitte um Hilfe
-
Du solltest die Daten nicht direkt da reinschreiben, sondern sie wo anders erstmal zwischenspeichern.
Zwischen den Threads solltest du auch eher mit Events kommunizieren, so das nur der Hauptthread in die GUI Elemente schreiben kann.phlox
-
Danke für die schnelle Antwort!
Meinst du mit Events Signal-Slot Verbindungen oder hat GTKmm eigene Events die man für so was benutzten kann?
Tscheburator
-
Sollte beides funktionieren, boost::signals2 ist threadsicher, bei GTK::Events müsstest du das noch abklären (afaik ja).
-
Tscheburator schrieb:
Danke für die schnelle Antwort!
Meinst du mit Events Signal-Slot Verbindungen oder hat GTKmm eigene Events die man für so was benutzten kann?
Tscheburator
Dafür nimmt man idR die sigc++ her, die ja auch von gtkmm verwendet wird
-
Danke für eure antworten.
Habe gerade noch ein Problem und zwar nutzt ich die ComboBox für die Auswahl der
COM Schnittstelle. Die angeschlossenen COM Schnittstellen werden aus dem Registry
ausgelesen und dort hinein gefügt. Wenn man jetzt während der Laufzeit eine
Virtuelle Schnittstelle z.B. FTDI-Chip anklemmt möchte ich das Programm nicht
ausschalten sondern habe ein Button hinzugefügt "Update COMx" bei Betätigung des
Buttons wird die Registry erneut eingelesen. Und jetzt kommt das Problem.
Bevor ich die Registry einlese will ich die ComboBox mit dem alten Inhalt löschen
mit "Gtk::ComboBox::erase()" meine Box habe ich folgend benannt "comboBox_comx"
daraus resultiert "comboBox_comx->erase()" hier mal der Programm teil:void Communication_Interface::initial_comboBox_comx()
{
unsigned char buffer[10];if(listStore_comx != NULL)
listStore_comx->clear();listStore_comx = Gtk::ListStore::create(*column_record);
comboBox_comx->set_model(listStore_comx);
for(unsigned long int counter = 0; read_registry(counter, buffer); counter++)
{
Gtk::TreeRow row = *(listStore_comx->append());
row[*treeModelColumn_name] = (char*)buffer;
row[*treeModelColumn_value] = counter;
}comboBox_comx->pack_start(*treeModelColumn_name);
comboBox_comx->set_active(0);
}Wenn ich das mache löscht er mir den Inhalt aber nicht raus sondern setzt mir
nochmal die erkannten Schnittstellen neben den alten. Es ensteht ein misch masch!Was ich schon probiert habe ist das ich das ich durch das betätigen des Button eine zwei Signale/Slot Verbindungen gemacht habe. Die erste Verbindung zum
löschen des Inhalts und die zweite zum neu einlesen, geht auch nicht.
Nach meiner Meinung sieht das aus als ob es die ComboBox erst nach der Durchführung der ganzen Funktion neu zeichnet oder so. Weil wenn ich die Signal/Slot Verbindung zum neu einlesen weg lasse und nur die zum löschen ausführen lasse dann löscht er den Inhalt raus.Was kann man da machen???
Bitte nochmal um Hilfe!
Falls der ganze Quellcode gebraucht wird bitte mitteilen!Gruß
Tscheburator
-
Entschuldigung habe ein Fehler in dem Text. Mit comboBox_comx->erase()
ist listStore_comx->clear() gemeint. Sorry