Seite 2 von 3

Verfasst: Samstag 31. Januar 2009, 18:04
von Leonidas
Was ist denn ``self.eins``. Wenn du darauf zugreifen willst, musst du es der Threadklasse zum Beispiel als Parameter mitgeben.

Verfasst: Samstag 31. Januar 2009, 18:12
von gugugs
ja genau das meine ich ja... was ist wenn aber jetzt self.eins eine funktion ist also z.B.:

klasse thread(threading.Thread)
funktion__init__(self)
threading.Thread.__init__(self)

funktion run(self)
funktion eins ausführbar? (nein)
self.zwei anzeigen?

klasse programm
funktion __init__(self)
funktion eins(self):
print "hallo"
self.zwei
self.drei
thread=thread
thread.start()


das meine ich ja variablen kann ich ja als parameter übergebn, aber was ist mit Funktionen, was ist wenn ich in der Thread Klasse eine Funktion benutzen will, die in der Klasse programm (das Beispiel) definiert wurde und eine instanz von der klasse programm ist?

Verfasst: Samstag 31. Januar 2009, 18:19
von EyDu
Dann übergibst du die Instanz als Parameter und speicherst diese als Attribut. Dann kannst du sie mit

Code: Alles auswählen

self.inst.eins()
aufrufen.

Von Vorteil wäre es, wenn du deinen Code noch zwischen die entsprechenden Code-Tags setzen könntest. Und natürlich richtigen Python-Code zu verwenden.

Edit:

Code: Alles auswählen

class Thread(threading.Thread):
    def __init__(self, programm):
        threading.Thread.__init__(self)
        self.programm = programm

    def run(self):
        self.programm.eins()

class Programm:
    def eins(self): 
        print "hallo" 

programm = Programm()
thread=Thread(programm )
thread.start() 

Verfasst: Samstag 31. Januar 2009, 18:31
von gugugs
Suuper, jetzt hab ichs verstanden. Vielen Danke für die ganze Geduld, und letzte perfekte Erklärung

Sry das es kein Code war, wollte ein schnelles Beispiel haben

Verfasst: Samstag 31. Januar 2009, 21:16
von gugugs
Tut mir leid, dass ich noch mal das Thema stören muss, aber wenn ich die Klasse oder Funktion so an den Thread weiter gebe, dann wird die Funktion schon beim weitergeben an den Thread aufgerufen, kann ich das irgendwie so machen, das diese erst aufgerufen wird, wenn ich sie im Thread aufrufe, und nicht schon bei der Übergabe?

Verfasst: Samstag 31. Januar 2009, 21:42
von Leonidas
Minimalbeispiel mit Code? Weil normalerweise passiert sowas nicht, wenn du eine Klasse oder Funktion herumreichst, es scheint dass du sie nicht übergibst, sondern aufrufst.

Verfasst: Samstag 31. Januar 2009, 21:49
von gugugs
Das mit dem Code posten, ist wirklich ein Problem, da es knapp 1000 Zeilen sind, und es alles verteilt ist, aber vom prinzip her hab ich 2 Klassen die eine ist die Thread Klasse, und die 2. die programm Klasse, die auch zu erst aufgerufen wird, da dort das Fenster und alle mögliche gemacht wird wird, wenn ich jetzt so mache, wie EyDu es schon beschrieben hat:

Code: Alles auswählen

class Thread(threading.Thread):
    def __init__(self, programm):
        threading.Thread.__init__(self)
        self.programm = programm

    def run(self):
        self.programm.eins()

class Programm:
    def eins(self):
        print "hallo"

programm = Programm()
thread=Thread(programm )
thread.start() 
Dann startet sich mein ganzes Fenster neu, hat das was damit zu tun, das ich in der Funktion programm, also in der Hauptfunktion eine __init__ drin habe, für das Fenster?
Denn ich habe es ganz genauso gemacht, wie in dem Beispiel von EyDu beschrieben

edit: allein wenn ich schon programm=programm() dann wird die Klasse neu aufgerufen, und ein neues Fenster erscheint

Wenn ich es so mache:

Code: Alles auswählen

class Thread(threading.Thread):
    def __init__(self, programm):
        threading.Thread.__init__(self)
        self.programm = programm

    #def run(self):
        #self.programm.eins()

class Programm:
	def eins(self):
		print "hallo"
		
print "hallo"

programm = Programm()
thread=Thread(programm )
thread.start() 
dann erscheint auch hallo, also scheinbar alles was nicht in einer Funktion ist, wird neu aufgerufen

Verfasst: Samstag 31. Januar 2009, 22:47
von Leonidas
Natürlich dass bei letzteren Beispiel auch ``hallo`` erscheint, du hast mitten im Modul ein ``print 'Hallo'``.

Code: Alles auswählen

import threading

class Thread(threading.Thread):
    def __init__(self, programm):
        threading.Thread.__init__(self)
        self.programm = programm

    def run(self):
        self.programm.eins()

class Programm:
    def eins(self):
        print "hallo"

programm = Programm()
thread = Thread(programm)
thread.start()
(So sieht ein Minimalbeispiel aus, also auch mit allen nötigen Imports) verhält sich genau so wie ich es erwarten würde. Was würdest du denn hier erwarten?

Verfasst: Samstag 31. Januar 2009, 23:06
von gugugs
Ja, stimmt ist mir dann auch aufgefallen, hab es jetzt auch so gemacht. Aber mir fällt auf, das selbst wenn in der Thread Klasse eine Funktion von der Programm Klasse aufgerufen wird, das die Programm Klasse zum Stillstand kommt, also mein Knopf immer noch gedrückt bleibt

Verfasst: Samstag 31. Januar 2009, 23:52
von Leonidas
Nunja, wie schon öfter gesagt, ohne einen Quellcode von dir der ein minimales, lauffähiges Beispiel zeigt (du kannst das etwa in das Pocoo-Pastebin laden) ist es nur schwer dir zu helfen.

Verfasst: Sonntag 1. Februar 2009, 00:14
von gugugs
So, das ist nun der ganze Quellcode:

[Edit (Leonidas): Quellcode ausgelagert.]

Es hilft mir nicht viel Falls mir jetzt jemand sagt, das es unordentlich ist oder die Variablen nicht gut bennant sind (das weiß ich selbst). Alle Funktionen in der Mitte sind eig. uninteressant, was mein Ziel ist, ist die on_download_clicked und die on_upload_clicked Funktion so zu "präparieren" das sie mein Programm nicht einfrieren, falls die Glade Datei noch benötigt wird, würde ich diese auch noch schicken.
Ich denke mal, das es daran liegen könnte, das wenn ich es mit einem Thread mache, ich ja ganze Funktionen übergeben muss, und da diese in der Main Klasse sind, wird diese dann halt aufgehalten

Danke

Verfasst: Sonntag 1. Februar 2009, 00:40
von Leonidas
gugugs hat geschrieben:Es hilft mir nicht viel Falls mir jetzt jemand sagt, das es unordentlich ist oder die Variablen nicht gut bennant sind
Deswegen habe ich um ein Minimalbeispiel gebeten. Es ist schon klar dass keiner einen nahezu 1000 Zeilen langen Quelltext analysiert der ohne Glade-Datei nicht mal richtig lauffähig ist.

Verfasst: Sonntag 1. Februar 2009, 00:43
von gugugs
Die Funktionen sind ziemlich verteilt, sonst wäre es wieder unklar gewesen, aber ich hätte es auslagern können, sry.

Weiß vllt du, oder jemand vllt schon einen Rat?

Verfasst: Sonntag 1. Februar 2009, 00:55
von BlackJack
Ja, aber das willst Du ja nicht hören. ;-)

Verfasst: Sonntag 1. Februar 2009, 00:57
von gugugs
Falls es mit dem Problem zusammen hängt, sicherlich

Verfasst: Sonntag 1. Februar 2009, 11:14
von BlackJack
Vielleicht mit dem Problem direkt nicht, aber das findet man ja nicht heraus, wenn man sich solch einen Quelltext nicht anschauen möchte, solange der *so* aussieht. :P

Verfasst: Sonntag 1. Februar 2009, 13:37
von gugugs
Ich denke, das Problem liegt daran, das ich wenn ich eine Funktionen in einen Thread übergeben würde und diese dann dort aufrufe, das er ja dann diese Funktion dann trotzdem in der Hauptklasse ausführt, und diese dann auch zum Stillstand kommt, kann das so sein?

Verfasst: Sonntag 1. Februar 2009, 13:46
von BlackJack
Wenn Du eine Funktion in einem anderen Thread ausführst als dem in dem die Ereignisverarbeitung der GUI läuft, dann darf die GUI nicht blockieren.

Edit: Ich sehe gerade, dass Du in dem Programm überhaupt gar keine Threads verwendest!?

Verfasst: Sonntag 1. Februar 2009, 14:27
von gugugs
Ja, ich hatte sie wieder weggemacht, weil er nichts gebracht hat. Aber wenn ich die ganze Upload Funktion z.B. in einen Thread mache, und die dazugehörigen anderen Funktionen, die die Upload Funktion benötigt, mit gebe, dann friert der GUI ein... Das habe ich nämlich schon ausprobiert...

Ich habe jetzt zum testen den Code mal so geändert, das ist nur oben:

Code: Alles auswählen

class my_thread(threading.Thread):
	def __init__(self):
		threading.Thread.__init__(self)
	
	def run(self):
		self.xml = gtk.glade.XML(os.path.join(os.path.dirname(sys.argv[0]), "linkcc_0.2.2.glade"))
		
		self.window=self.xml.get_widget("progressbar")
		self.window.show_all()

class programm:
........
.....
...
....
Wenn ich den Thread nun mit dr Upload Funktion starte, dann öffnet sich das Fenster erst, wenn in der Upload Funktion alles abgelaufen ist, und dort alles fertig ist. Vorher bleibt das Fenster weg. Müsste sich das Fenster nicht eig. öffen? Habe in der on_upload_clicked Funktion den Thread ganz normal an erster Stelle aufgerufen, und trotzdem klappt es nicht.

Verfasst: Montag 2. Februar 2009, 13:46
von Trundle
Du zeigst hier nicht, wie du den Thread startest. Rufst du z.B. die `run`-Methode anstatt der `start`-Methode auf, dann wird da kein neuer Thread gestartet, sondern die `run`-Methode wir im selben Thread augeführt. Und grundsätzlich ist es eine schlechte Idee, mit mehreren Threads gleichzeitig auf die GUI zuzugreifen. Wurde aber schön öfters im Forum diskutiert, die Suchfunktion liefert da bestimmt etwas.