Anwendung reagiert nicht mehr

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Ich habe einen seltsamen Effekt in meiner Anwendung. Unter bestimmten Umständen reagiert sie auf (fast) nichts mehr. Die Widgets nehmen keinen Fokus mehr an, die Buttons reagieren nicht mehr, Menüs funktionieren auch nicht mehr. Die einzigen Events die erkannt werden, ist Mausradscrollen und ein Klick in die Titelleiste des Fensters.

Es gibt zwei Möglichkeiten die Anwendung aus dem Schlaf zu wecken:
- Klick auf die Titelleiste
- Alt-Tab (also Anwendungswechsel) bis man wieder bei der App ist
Danach reagieren alle Widgets wieder ganz normal.

Der Effekt entsteht so:
- function A definiert callback C
- callback C ruft function A erneut auf
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Meine Glaskugel ist gerade ausgefallen ;-) Poste mal ein minimales Beispiel, bei dem der Fehler auftritt.
Das Leben ist wie ein Tennisball.
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Ich sehe mich ausserstande ein minimales Beispiel zu basteln bei dem der Effekt auftritt. Kann ich auch die ganze Anwendung posten?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Streiche zumindest so viel wie möglich. Das erhöht deine Chancen, dass sich jemand genauer mit dem Code beschäftigt. Keiner hat lust sich durch hunderte von Zeilen zu wühlen.

Wenn es mer als eine Seite Code wird, dann solltest du den am besten auslagern. Das Forum hat ein wenig Probleme mit zu viel Code.
Das Leben ist wie ein Tennisball.
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Die Anwendung ist hier:

https://launchpad.net/unitree/+download

Kurzanleitung zur Reproduktion des Effektes:
1. zip downloaden und in beliebiges Verzeichnis entpacken
2. Auf Konsole in dieses Verzeichnis wechseln
3. Anwendung starten mit: python unitree.py
4. F1 drücken (damit Hilfedatei geladen wird)
5. Im Baum auf einen Eintrag navigieren der ein unterstrichenes Wort enthält
6. Doppelklick auf dieses Wort
7. Anwendung friert ein

Der Effekt tritt in Codezeile 1392 auf wenn die Methode zum Anzeigen der Attribute auf der rechten Seite erneut aufgerufen wird.
Zuletzt geändert von rhersel am Mittwoch 5. August 2009, 22:31, insgesamt 1-mal geändert.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Hab ich das richtig verstanden, dass du die Callback-Funktion neu definierst, während du die "alte" Callback-Funktion ausführst?
Hört sich IMO nach einer unsauberen Lösung an...
rhersel
User
Beiträge: 105
Registriert: Mittwoch 3. Dezember 2008, 11:29

Nein, habe die Callback Funktion nicht neu definiert.
Habe gerade festgestellt, dass der Fehler nur unter Linux (Ubuntu 9.04) aber nicht unter Windows XP auftritt.

Hier ist trotzdem mal der betreffende Code-Ausschnitt (stark gekürzt):

Zur Erklärung:
Die Funktion show_attributes baut u.a. eine Textbox auf und füllt sie mit Daten. Für diese Textbox wird der Doppelklick im Callback 'event_textview_button_press' behandelt. Falls hier ein paar Bedingungen zutreffen, wird ein Element in einem Treeview ausgewählt und die Funktion show_attributes wieder aufgerufen um den Text zu diesem Element anzuzeigen. Dann reagiert die Anwendung nicht mehr normal (siehe Beschreibung oben). Mit einem Klick auf die WindowKopfzeile ist dann alles wieder normal.

Code: Alles auswählen

def show_attributes(self, node):												# show the attributes of the selected row in the right pane
	if node:																	# do we have a selected node?
		for widget in self.vbox_right.get_children():	   						# iterate over all widgets in this container
			widget.hide()								   						# hide all widgets in this container	
		if node.type == 'kid':
			# Create Liststore and Listview
		elif node.type == 'ins':
			self.auto_indent = 0												# reset auto indent
			rows = len(node.parent.atr)							 				# how many attributes
			self.table = gtk.Table(rows, 3, False)				  				# create the table container
			self.table.set_row_spacings(5)						  				# set row spacing
			index = 0											   				# attribute counter
			for atr in node.parent.atr:							 				# for each attribute
				type = atr.type									 				# get the attribute type
				if type == 'note':												# note
					self.frame = gtk.Frame(label=None)			  				# create a frame
					self.frame.set_shadow_type(gtk.SHADOW_IN)	   				# set shadow
					self.textview = gtk.TextView()				  				# create textview
					self.textview.set_wrap_mode(gtk.WRAP_WORD_CHAR) 			# how text breaks at line end
					self.textbuffer = self.textview.get_buffer()				# create textbuffer
					self.textbuffer.create_tag('underline', underline=True)		# create tags
					self.frame.add(self.textview)				   				# put textview into frame
					if index == 0:								  				# Description
						self.vbox_right.pack_start(self.frame, True, True, 0)   # not in table but in vbox
					else:													   	# it is a Note but not the Description Note
						self.table.attach(self.frame, 1, 3, index, index+1)		# left, right, top, bottom
					self.textbuffer.set_text(node.atr[index])					# put description in textbuffer
					self.textbuffer.connect("changed", self.event_textbuffer_changed, index)		# Textbuffer was changed
					self.textview.connect('focus-out-event', self.event_textview_focus_out)			# Focus leaves widget
					self.textview.connect('button-press-event', self.event_textview_button_press)	# Mouseclick in textview
					self.textview.connect('key-press-event', self.event_textview_key_press)			# Key pressed in textview
					
					if self.cfg['show_textlinks']: self.word.mark(self.textbuffer, node.name)	# mark dictionary word in textbuffer
					self.textview.show()										# show textview
					self.frame.show()							   				# show frame
					self.textbuffer.set_modified(False)			 				# reset modified flag
				
				index += 1										  							# increment attribute counter

			self.table.show()									   							# show the table
			self.vbox_right.pack_start(self.table, False, True, 0)  						# put table into vbox
			
def event_textview_button_press(self, widget, event):						# mouse button clicked in textview
	if event.button == 1 and event.type == gtk.gdk._2BUTTON_PRESS:			# left mouse button 2clicked
		textbuffer = widget.get_buffer()									# get textbuffer from textview
		cursor_mark = textbuffer.get_insert()								# get mark of cursor position
		iter = textbuffer.get_iter_at_mark(cursor_mark)						# get iter at cursor position
		tag_table = textbuffer.get_tag_table()								# get tag table from textbuffer
		tag_underline = tag_table.lookup('underline')						# get tag from table			
		if iter.has_tag(tag_underline):										# text is underlined
			while not iter.begins_tag(tag_underline): iter.backward_char()	# find start of tag
			start_iter = iter.copy()										# save start position
			while not iter.ends_tag(tag_underline): iter.forward_char()		# find end of tag
			end_iter = iter.copy()											# save end position
			text = unicode(textbuffer.get_text(start_iter, end_iter, True))	# get text
			path = self.word[text]											# get path
			self.treeview.expand_to_path(path)								# expand treeview to this item
			treeselection = self.treeview.get_selection()					# get a selection object
			treeselection.select_path(path)									# select the found item in tree
			self.treeview.scroll_to_cell(path, None, True, 0.5)				# scroll treeview to the correct position
			node = self.get_selected_node()									# get reference of selected node
			self.show_attributes(node)									  	# show the attributes of the selected row in the right pane
[/code]
Antworten