Schleife per Button beenden

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
DMD-OL
User
Beiträge: 315
Registriert: Samstag 26. Dezember 2015, 16:21

hi
ich habe mein problem: "das auslesen einer 3GB großen Textdatei per Button abzubrechen"
gemäß euren tipps versucht umzusetzen.
aber kurz vorm ziel komm ich mal wieder nicht klar...

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

try:
    # Tkinter for Python 2.xx
    import Tkinter as tk
except ImportError:
    # Tkinter for Python 3.xx
    import tkinter as tk

import codecs
import os

from threading import Thread
from Queue import Queue

source_filename = "C:\Users\DMD-OL\Desktop\Handy-Datenbank\DATANORM\DATANORM.002"
TIME_STEP = 1000 # Milliseconds
LABEL_WIDTH = 3
LABEL_FONT = ('Helevetica', 20, 'bold')


def start():
    if not root.running:
        root.running = True
        counter()
        process_file(source_filename)

def counter():
    if not root.running: return
    root.after(TIME_STEP, counter)

def stop():
    root.running = False

#######
#Auslesen einer 3GB großen Textdatei
#######
def process_file(source_filename):

    # AN DIESER STELLE HÄTTE ICH GERN NACH JEDEM TIME_STEP DIE AKTUELLE AUSGABE VON "root.running" nach 1000 millisekunden
    print root.running

    # DAMIT ICH MIT
    #while root.running:
    #    worker_queue = Queue()
    #    finished = object()
    #    def process(queue, line):
    #        queue.put(line)
    #    def read():
    #        with open(source_filename) as source:
    #            for line in source:
    #                queue = Queue()
    #                Thread(target = process, args=(queue, line)).start()
    #                worker_queue.put(queue)
    #        worker_queue.put(finished)
    #    Thread(target = read).start()
    #    for output in iter(worker_queue.get, finished):
    #        print output.get()


root = tk.Tk()
root.config(relief='groove', bd=2)

root.running = False

app = tk.Frame(root)
app.grid(padx=5, pady=5)

tk.Button(app, text="Start", command=start).pack(pady=2) #process_file(source_filename)
tk.Button(app, text="Stop", command=stop).pack()

root.mainloop()
ich habe probleme mit der vorherigen überprüfen der variablen "root.running" jedesmal bevor eine neue zeile ausgelesen wird :(
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@DMD-OL: warum baust Du für Tkinter eine Python2/3-Weiche ein, wenn der Rest des Skripts Python2-only ist? `root` kommt auf magische Weise in die Funktion `start`. Das sollte ein Parameter sein, oder Du schreibst eine Klasse und start als Methode. `counter` macht bisher noch nichts sinnvolles.

In `process_file` ist so einiges schief. Die while-Schleife ist unsinnig, da Du ja in einem Schleifendurchgang die gesamte Datei liest. Du startest zwar einen read-Thread, wartest dann aber auf alle Ergebnisse dieses Threads. Damit hast Du wieder eine blockierende GUI-Funktion, und Du könntest den ganzen Thread-Overhead sparen. Da Du die Datei sowieso nur auf der Konsole ausgibst, kannst Du Dir auch den ganzen GUI-Overhead sparen. Um daraus eine sinnvolle Anwendung zu machen, solltest Du nur z.B. die Anzahl der Zeilen in einem Label anzeigen. Dazu startest Du einen Thread und kehrst sofort wieder zurück. In einer after-`Schleife`, wie Du sie schon in counter hast, liest Du die Anzahl gelesener Zeilen aus, dazu brauchst Du dann auch keine Queue, die beim Lesen einer Datei sowieso ständig vollgestopft wäre, so dass die GUI deshalb blockiert.

Innerhalb der Funktion `read` machst Du noch viel mehr schiefe Dinge. Es macht keinen Sinn, für jede Zeile einen neuen Thread zu starten, damit startest Du Millionen an Threads, die Dein ganzes System lahmlegen. Es macht auch keinen Sinn, jeweils eine Queue in eine Queue zu stecken.

Alles ab Zeile 62 gehört in eine Funktion, so dass Du gar nicht erst in Versuchung gerätst, `root` als globale Variable zu benutzen.
Antworten