Fortlaufen eines Programms???

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
meister56
User
Beiträge: 57
Registriert: Dienstag 23. Dezember 2008, 22:54

Fortlaufen eines Programms???

Beitragvon meister56 » Mittwoch 24. Dezember 2008, 10:35

Ich versuche gerade Tetris in python zu programmieren und es ist mir auch schon fast alles gelungen, doch bei mir ist ein Problem aufgetaucht!
Ich weis nicht wie ich die Anweisung geben kann das pro eine bestimmte Zeit etwas geschehen soll (hier das runterbewegen der Figuren)
Kann mir jem. raueshelfen? :?: [/code]
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Mittwoch 24. Dezember 2008, 10:45

ein zeitgesteuerter thread?

Code: Alles auswählen

import threading, time

class T (threading.Thread):
    def run(self):
        while 1:
            mache_etwas()
            time.sleep(0.1)


Diese Klasse ruft dann alle Zentelsekunde die Funktion mache_etwas auf.

Start der Schleife:

Code: Alles auswählen

t = T()
t.start()


Ich hoffe, dass ich dich richtig verstanden habe :D
meister56
User
Beiträge: 57
Registriert: Dienstag 23. Dezember 2008, 22:54

Beitragvon meister56 » Mittwoch 24. Dezember 2008, 11:17

so ehnlich habe ich es versucht, das problem dabei war das es durch das "time.sleep" das ganze program net mehr lief( du konntest dann gar keine zusäzlichen Buttons wie z.B. "Pause" drücken)!
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Mittwoch 24. Dezember 2008, 11:23

Code: Alles auswählen

import threading, time

class T (threading.Thread):
    def __init__(self):
        threading.__init__(self)
        self._paused = 0
    def run(self):
        while 1:
            if (self._paused): continue
            mache_etwas()
            time.sleep(0.1)



und dann kannste mit

Code: Alles auswählen

t._paused = 1
das ganze anhalten und mit

Code: Alles auswählen

t._paused = 0
das ganze wieder starten:

Code: Alles auswählen

t = T()
t.start()

t._paused = 1 # pause
t._paused = 0 # weiter
meister56
User
Beiträge: 57
Registriert: Dienstag 23. Dezember 2008, 22:54

Beitragvon meister56 » Mittwoch 24. Dezember 2008, 11:35

ok danke für die Hilfe!
mal sehn ob es funktioniert!
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Beitragvon sma » Mittwoch 24. Dezember 2008, 11:56

Birne94 hat geschrieben:

Code: Alles auswählen

        while 1:
            if (self._paused): continue

Dies ist eine ganz üble Warteschleife, die 100% der Rechnenleistung frist und die es zu vermeiden gilt. Es wird auch in Python bessere Wege geben, einen Thread anzuhalten, etwa indem man auf eine Semaphore wartet.

Bei der GUI-Programmierung sollte man lieber auf Threads verzichten, denn fast kein GUI-Rahmenwerk ist threadsafe. Üblicherweise - ich kenne mich mit Python-GUIs leider nicht aus - kann man einen Zeitgeber benutzen, über den man sich einmalig oder periodisch aufrufen kann.

Frohe Weihnachten
DasIch
User
Beiträge: 2423
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 24. Dezember 2008, 12:51

@sma Deswegen ist ja noch das time.sleep mit drin ;) Trotzdem unschön gerade bei GUI Toolkits sollte das mit Events machbar sein, bei PyQt4 ist dass aufjedenfall kein Problem im Thread auf ein Event zu reagieren.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Beitragvon Trundle » Mittwoch 24. Dezember 2008, 12:56

@DasIch: wenn ``bool(self._paused)`` True ergibt, dann ist da kein sleep drin und es frisst alle Rechenleistung. Außerdem braucht man für periodische Aufrufe eigentlich keine Threads, weil das wirklich jedes Toolkit können müsste.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Mittwoch 24. Dezember 2008, 13:10

Code: Alles auswählen

import threading, time

class T (threading.Thread):
    def __init__(self):
        threading.__init__(self)
        self._paused = 0
    def run(self):
        while 1:
            if (self._paused): continue
            time.sleep(0.1)
            mache_etwas()


stimmt. ist mir auch schon aufgefallen.
und dass es nicht das Beste ist, ist mir auch klar ;-)
DasIch
User
Beiträge: 2423
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Mittwoch 24. Dezember 2008, 13:23

Ändert auch nichts, verwende `pass` statt `continue`.
Birne94
User
Beiträge: 90
Registriert: Freitag 28. November 2008, 15:18
Kontaktdaten:

Beitragvon Birne94 » Mittwoch 24. Dezember 2008, 13:54

Code: Alles auswählen

import threading, time

class T (threading.Thread):
    def __init__(self):
        threading.__init__(self)
        self._paused = 0
    def run(self):
        while 1:
            time.sleep(0.1)
            if (not self._paused):
                mache_etwas()


so besser?
lunar

Beitragvon lunar » Mittwoch 24. Dezember 2008, 14:02

DasIch hat geschrieben:@sma Deswegen ist ja noch das time.sleep mit drin ;) Trotzdem unschön gerade bei GUI Toolkits sollte das mit Events machbar sein, bei PyQt4 ist dass aufjedenfall kein Problem im Thread auf ein Event zu reagieren.

Ich denke, du verwechselt hier Signale mit Ereignissen. Ereignisse, die vom Rahmenwerk (ich wollte dieses Wort auch mal verwenden, sma ;) ) ausgelöst werden, sind keinesfalls threadsicher. Konkret bedeutet das, dass ein PaintEvent z.B. nicht threadübergreifend funktioniert. Es kann daher einzig und allein der Hauptthread auf ein Widget zeichnen. De fakto ist Qt4 genauso wenig threadsicher wie jedes andere GUI-Toolkit. Das ist technisch auch völlig sinnvoll, da paralleles Zeichnen weitreichende Synchronisationsprobleme mit sich bringen würde. Was passiert z.B. wenn zwei Threads parallel auf dieselbe Fläche zeichnen? Das ließe sich nur über komplexes Locking lösen, mit entsprechend negativen Auswirkungen auf die Performance.

Signale und Slots in Qt4 dagegen sind threadsicher (aber eben auch etwas anderes als Ereignisse, deswegen heißen sie ja auch anders ;) ). Allerdings laufen threadübergreifende Verbindungen zwischen Signalen und Slots über eine Queue, Sender und Empfänger leben also in verschiedenen Threads. Wenn z.B. ein QThread ein Signal aussendet, welches mit QLabel.setText verbunden ist (z.B. für eine Statusanzeige), dann läuft QLabel.setText nicht im QThread, sondern im Hauptthread des Programms (der die GUI erzeugt hat) ab.

Im Übrigen wäre ein Thread zur Lösung des gestellten Problems in Qt4 völlig deplaziert, QtCore.QTimer existiert.
BlackJack

Beitragvon BlackJack » Mittwoch 24. Dezember 2008, 14:03

@meister56: Welches GUI-Toolkit verwendest Du denn nun?

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder