Log-Auswerter; Live Verfolgung des Statuses

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

Moin,
Ich saß schon vor paar Monaten an einem Tool das mir Automatisch Logs auswerten sollte. (http://www.python-forum.de/topic-20953.html)

Hatte das Teil damals Frustriert liegen gelassen weil ichs einfach net Verstand.
Inzwischen hab ich was dazugelernt, hab das Script aufgeräumt und mir gleich gedacht, hey, verpack es doch gleich in ne GUI!

Hja... an sich kein Problem.
Leider bin ich auf etwas gestoßen was ich vorher nie gemacht hatte.
Ich will das wenn mein Button im "Checked" Status ist, mein Skript ausgeführt wird.

Das tut er auch... Leider führt er es tatsächlich mehr oder weniger endlos aus und wartet bis irgendwann diese Schleife unterbrochen wird...
Das ist aber erst am ende des Uploads aber der soll mir auch den Zwischenstand sagen!

Wie Löse ich
dieses Problem?
(Relevantes ab Zeile 44)


EDIT: So wie ich jetzt durch andere Threads rausgefunden habe, ist das was ich brauche dasmit das ganze Funktioniert entweder, das der Knopf in einem gewissen Intervall gedrückt wird wie die QButton.AutoRepeat Funktion (nur das diese wenn ich recht verstand nur bei nem Shortcut aktiviert wird) oder das hier als Schwer bezeichnete Threading.

Hab das letztere ausprobiert. Einmal über Pythons Thread und einmal über QThread. Aber ich hab da nicht ganz durchgeblickt was, warum ichs tu. Deswegen Funktionierte es wohl auch nicht,



Code: Alles auswählen

from PyQt4 import QtCore, QtGui
import os
import time

class Ui_LOGAuswerter(object):
    def setupUi(self, LOGAuswerter):
        LOGAuswerter.setObjectName("LOGAuswerter")
        LOGAuswerter.resize(378, 247)
        self.centralwidget = QtGui.QWidget(LOGAuswerter)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayoutWidget = QtGui.QWidget(self.centralwidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(10, 10, 351, 231))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.textEdit = QtGui.QTextEdit(self.verticalLayoutWidget)
        self.textEdit.setObjectName("textEdit")
	self.textEdit.setReadOnly(True)
        self.verticalLayout.addWidget(self.textEdit)
        self.horizontalLayout = QtGui.QHBoxLayout()
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.pushButton = QtGui.QPushButton(self.verticalLayoutWidget)
        self.pushButton.setCheckable(True)
        self.pushButton.setFlat(False)
        self.pushButton.setObjectName("pushButton")
        self.horizontalLayout.addWidget(self.pushButton)
        self.pushButton_2 = QtGui.QPushButton(self.verticalLayoutWidget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.horizontalLayout.addWidget(self.pushButton_2)
        self.verticalLayout.addLayout(self.horizontalLayout)
        LOGAuswerter.setCentralWidget(self.centralwidget)

        self.retranslateUi(LOGAuswerter)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("toggled(bool)"), self.starts)
        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL("clicked(bool)"), LOGAuswerter.close)
        QtCore.QMetaObject.connectSlotsByName(LOGAuswerter)

    def retranslateUi(self, LOGAuswerter):
        LOGAuswerter.setWindowTitle(QtGui.QApplication.translate("LOGAuswerter", "LOG Auswerter", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("LOGAuswerter", "Start", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("LOGAuswerter", "Beenden", None, QtGui.QApplication.UnicodeUTF8))

    def starts(self):

 	beendet = True

	 def suche():
  
	   f = open('/home/sepl/Test_Programme/test.txt', 'r')
	   lesen = f.readlines()[-4:]
	   lesen

	   if str(lesen).find('erfolgreich') != -1:
	     self.textEdit.insertPlainText("Transfer wird fortgesetzt.\n")
	     self.textEdit.ensureCursorVisible()
 
	   elif str(lesen).find('ERROR') != -1:
	     self.textEdit.insertPlainText("Tranfser Fehlgeschlagen. Bitte Neustarten!\n")
	     self.textEdit.ensureCursorVisible()
	     exit()

	   elif str(lesen).find('Transfer Beendet') != -1:
	     self.textEdit.insertPlainText("Transfer Erfolgreich beendet!\n")
	     self.textEdit.ensureCursorVisible()
	     exit()

	   else:
	     self.textEdit.insertPlainText("Problem: Fehlende Informationen?\n")
	     self.textEdit.ensureCursorVisible()
	     exit()

	   f.close()


	 while beendet:

	   suche()
	   time.sleep(5)

	 else: 
	   self.textEdit.insertPlainText("Programm beendet")
Gruß, Vondor
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Zu Deinem Grundproblem:
Die while-Schleife mit dem sleep wird nie verlassen, da die Abbruchbedingung immer `True` ist. Das Programm "hängt" hier fest, der Eventloop wird nicht mehr erreicht und ergo erfolgt auch keine Ausgabe - die GUI friert ein.
Damit das funktioniert, musst Du den Code so umschreiben, dass zwischen den Leseaktionen in `suche()` der Eventloop von Qt zum Zuge kommt. Zusammen mit Deinem CheckedButton und QTimer ginge das schematisch so:
- knüpfe `checked`-Status des Buttons an einen Intervall-Timer
- Timer prüft in Abständen Datei und füllt Textbox (analog zu `suche()`)
- `unchecked`-Status des Buttons stoppt den Timer
Das lässt sich auch mit Threads realisieren, welcher Weg hier sinnvoller ist, hängt davon ab, wie die Hauptapplikation aufgebaut ist (Achtung: auf GUI-Elemente immer nur über den Hauptthread zugreifen, d.h. die Log-Infos müsstest Du zum Hauptthread rüberreichen und dort zur Anzeige bringen)

Sonstiges:
An Deinem Code ist einiges komisch:
- Du nutzt unterschiedliche Einrückungen
- Dateiaktionen ohne Ausnahmebehandlunen
- längere elif-Konstrukte lassen sich meist durch ein Wörterbuch ersetzen
- Dein Code steht in der der ui->py Datei. Ist das gewollt? (Änderungen gehen verloren nach erneutem pyuic-Aufruf)
- Was macht das `exit()` da?
- while-Bedingung ist immer erfüllt

Vielleicht helfen Dir die Denkanstösse weiter.

Grüsse Jerch
...
User
Beiträge: 116
Registriert: Mittwoch 23. Dezember 2009, 20:22

Das 'exit()' soll wohl bewirken, das das Programm abbricht.

Die Endlosschleife ist also gewollt... Sie läuft solange, bis die aufgerufene Funktion das Programm gleich ganz beendet...

Allerdings glaube ich, müsste er dafür anfangs noch einfügen:

from sys import *


oder zumindest (besser)
import sys

und exit() durch sys.exit() ersetzen.
Oder gibts exit() auch so?
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

jerch hat geschrieben:mit Deinem CheckedButton und QTimer ginge das schematisch so
Genau das ist die Lösung die ich gesucht habe!
Ich versuchte das mit der Repeat Funktion vom Button hinzubekommen.
Aber das war halt das Falsche.

Werd es morgen früh ausprobieren.

jerch hat geschrieben: 1. Du nutzt unterschiedliche Einrückungen
2. Dateiaktionen ohne Ausnahmebehandlunen
3. längere elif-Konstrukte lassen sich meist durch ein Wörterbuch ersetzen
4. Dein Code steht in der der ui->py Datei. Ist das gewollt? (Änderungen gehen verloren nach erneutem pyuic-Aufruf)
5. Was macht das `exit()` da?
6. while-Bedingung ist immer erfüllt
1. Jain... eigentlich nur Tabs... Aber beim Kopieren ins Forum hab ich bemerkt das er trotzdem iwie net alle im Gleichen abstand gemacht hat...
Ich schieb die schuld einfach mal aufn Editor XD
Deswegen hab ichs bisl.. Ähm, Nachgebessert was wohl aufgefallen ist^^

Im Orginal sind alle Einrückungen einheitlich.

2. Kommt noch...

3. Muss ich nochmal nachlesen^^

4. Ja und nein. Bisher hab ich das grobe per Designer gemacht und dann einfach feinheiten mit allen Funktionen selber Ergänzt und das in die ui Datei... Ich entnehme dem das ich das nicht so machen sollte.. Ich besser mich^^

5. S.u. :P

6. Vorstatus halt^^


... hat geschrieben:Das 'exit()' soll wohl bewirken, das das Programm abbricht.
Jup, das ist ne Vor-Version für mich.
Das wird später noch Bereinigt...^^

Ist noch aus der Zeit wo das ganze ein Reines Skript ohne GUI war.





Dankeschön :P
ichisich
User
Beiträge: 134
Registriert: Freitag 1. Januar 2010, 11:52

4. Ja und nein. Bisher hab ich das grobe per Designer gemacht
und dann einfach feinheiten mit allen Funktionen selber Ergänzt und das in die ui Datei... Ich entnehme dem das ich das nicht so machen sollte.. Ich besser mich^^
Ha das kannst Du halten wie der auf dem Dach :lol:

Wenn Du aber wieder was im Designer änderst wird dein ui_xyz.py-File
ohne Fragen überschrieben und dann machst du deine Feinheiten halt
noch mal.
Zur Übung, nicht zur Strafe natürlich :lol:

eine Möglichkeit wäre Du machst eine Klasse und erbst alles von deinem Ui-File:

Code: Alles auswählen


import ui_LOGAuswerter

class LOGAuswerter(ui_LOGAuswerter.Ui_LOGAuswerter)
             def __init__(self, parent = None):
             super(LOGAuswerter, self).__init__(parent)
            
# hier Zugriff auf deine Methoden im Ui-File
             self.setupUi(self)

            self.pushButton_2.setEnabled(False)
# oder was auch immer
Dann kannst Du auf alle Attribute zugreifen.

(Ich hoffe ich hab nichts vergessen)
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

Bin grad Fertig geworden.
Hat nur länger gedauert als ich dachte bis ich die Datei in den Händen hatte XD

Habs in 2 Dateien aufgespalten. Einmal der Initialisierenden und einmal der Ui. Alles Individuelle hab ich dabei in die Initialisierende gepackt.

Gleichzeitig noch paar Feinheiten am Skript geändert :)

Nu bin ich glücklich^^ Danke^^
Antworten