Frame öffnet "zu spät"

Fragen zu Tkinter.
Antworten
Pykons
User
Beiträge: 11
Registriert: Dienstag 14. Februar 2017, 09:45

Hallo liebe Gemeinde!

Ich schreibe aktuell ein recht komplexes Berechnungsprogramm für meine Abschlussarbeit (nein, nicht in Informatik, weshalb mir wohl an einigen Stellen ein "paar" Grundlagen fehlen... :? ). Grundsätzlich funktioniert Alles bisher ganz wunderbar! Jetzt bin ich aber auf folgendes Problem gestoßen:
Da die gesamte Berechnung, die während eines Programmdurchlaufs durchlaufen wird, einige Zeit in Anspruch nimmt, möchte ich den User über eine Progressbar über den Fortschritt informieren.
Drückt der User nach seinen Dateneingaben auf den Button zum Starten der Berechnung, wird eine Funktion (check(self)) gestartet, die der Reihe nach verschiedene Unterfunktionen aufruft, damit diese die dort definierten Berechnungen durchlaufen.
Nun habe ich die Funktion check(self) um einen Punkt erweitert. Bevor die Unterfunktionen der eigentlichen Berechnungen aufgerufen werden, wird eine weitere Funktion (ladebalken(self)) gestartet. Diese soll einen neuen Frame öffnen, auf dem dann die Progressbar plaziert werden kann.

Leider wird die Funktion check(self) erst vollständig durchlaufen und DANN erst wird der neue Frame geöffnet....allerdings benötige ich dann die Progressbar auch nicht mehr, da zu diesem Zeitpunkt die Berechnungen ja bereits zu 100% abgeschlossen sind! Ich habe jetzt schon einiges recherchiert, geändert, getan, gemacht und komme beim besten Willen nicht weiter... :K Ich wäre für jede Hilfe dankbar!

Ich vermute, dass es irgendwas mit der Funktion mainloop() zu zun hat?! Aber begründen kann ich auch das nicht, dazu fehlen mir vermutlich leider schlichtweg die Kenntnisse...

Um mein Problem zu veranschaulichen habe ich ein kleines Beispielprogramm geschrieben, in dem exakt das gleiche Problem auftritt.

Vielen vielen Dank schon jetzt für eure Hilfe!

Code: Alles auswählen

import tkinter
import time


class Berechnungsprogramm:
    def __init__(self):
        self.master=tkinter.Tk()
        self.master.title("Berechnungsprogramm")  
        self.master.resizable(0,0)
        self.frame1()

    def frame1(self):
        self.mainframe=tkinter.Frame(height=400, width=400, bg="yellow")
        self.button=tkinter.Button(text="Berechnung", command=self.check)
        self.label_1=tkinter.Label(text="", bg="yellow", fg="black", font=("Arial",20))
        self.mainframe.pack()
        self.button.place(x=4, y=370)
        self.label_1.place(x=50, y=50)
        self.mainframe.mainloop()

    def check(self):
        self.ladebalken()
        time.sleep(3)           # Ich möchte, dass das Programm etwas Zeit benötigt, um komplett ausgeführt werden zu können.
                                # Darum pausiere ich es hier an dieser Stelle. Dadurch sehe ich, dass der neue Frame mit dem
                                # Text "Anzeige" erst NACH Ablauf des Unterprogramms calculate erstellt wird....
                                # Ich verstehe leider nicht wieso, denn eigentlich wird es doch von der Funktion check() vor
                                # den Funktionen calculate_2() und calculat_2() aufgerufen und ausgeführt...
        self.calculate_1()
        self.calculate_2()

    def ladebalken(self):
        # Hier soll nun in meinem eigentlichen Programm ein Frame geöffnet werden und über meinem mainframe liegen.
        # Auf diesem neuen Frame soll eine Progressbar über den Fortschritt der Berechnungen informieren.
        # Simbolisch dafür steht hier einfach nur ein Label mit einem Text.
        self.hintergrund=tkinter.Frame(master=self.mainframe, height=100, width=200, bg="black")
        self.vordergrund=tkinter.Frame(master=self.hintergrund, height=96, width=196, bg="white")
        self.label_2=tkinter.Label(master=self.vordergrund, text="Anzeige", font=("Arial", 14), bg="white", fg="black")

        self.hintergrund.place(x=100, y=180)
        self.vordergrund.place(x=2, y=2)
        self.label_2.place(x=5, y=5)

    def calculate_1(self):
        # Hier werden jetzt einige Berechnungen durchgeführt, die ein paar
        # Sekunden in Anspruch nehmen. Deshalb soll eine Progressbar über den
        # Fortschritt informieren.
        # Die Berechnungen sollen hier durch eine einfache (und hier sinnlose)
        # Variablenzuweisung simbolisiert werden:
        sinnlosaktion=0
        self.label_1.config(text="Hallo Welt")

    def calculate_2(self):
        # Im eigentlichen Programm gibt es 10 solcher Unterfunktionen die für die Berechnung durchlaufen werden müssen.
        # Ich habe jetzt hier in diesem Beispielprogramm zwei Funktionen stellvertretend niedergeschrieben.
        sinnlosaktion=0

app=Berechnungsprogramm()
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Pykons: so funktioniert GUI- aka ereignisgesteuerte Programmierung nicht. Grundvoraussetzung ist, dass das Programm eigentlich fast die gesamte Zeit in mainloop auf Ereignisse wartet. Um also im Hintergrund Berechnungen durchführen zu können, brauchst Du Threads mit all den Schwierigkeiten, die die Kommunikation zwischen Rechenthread und Anzeige mit sich bringt. Ob sich der Aufwand für einen Fortschrittsbalken lohnt, sei Dir selbst überlassen.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Pykons: Ja so ist es. Kennst Du andere GUIs oder matplotlib? Da definiert man Widgets oder Grafiken. Die sind dann definiert in den internen Datenstrukturen. Danach ruft man deine Methode auf, die das Definierte zeichnet In tkinter braucht man eine solche Methode zum Zeichnen nicht selber aufrufen - weiß auch nicht, ob es die zum Aufrufen gibt - jedenfals tkinter ruft sie selber auf, nachdem die callbackroutine zu Ende ist. So wie jetzt kannst Du Fortschrittsbalken neu definieren, wie du willst und ändern, aber gezeichnet wird er erst, wenn die Berechnung fertig ist.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Pykons: Was Sirius3 da geschrieben hat, stimmt so nicht, denn Threads sind nicht schwierig und man sollte sie kennen.
Sirius3 hat geschrieben:Um also im Hintergrund Berechnungen durchführen zu können, brauchst Du Threads mit all den Schwierigkeiten, die die Kommunikation zwischen Rechenthread und Anzeige mit sich bringt. Ob sich der Aufwand für einen Fortschrittsbalken lohnt, sei Dir selbst überlassen.
Was schwieriger ist als Threads, ist es, seinen Code so zu schnipseln, wie Du es gemacht hast. Auch ich mußte viele Jahre so implementieren, weil das Programm schnell laufen mußte und Threads viel Verwaltungsaufwand und verlorene Zeit für das Betriebssystsem bedeutet hätten. Also hieß es, den Code zu portionieren, und wenn ein Codeabschnitt fertig ausgeführt war, wieder in das Betriebssystem zurückkehren lassen und dafür zu sorgen, daß es uns später wieder für das nächste Codeschnipsel aufrief,

Da Du ja bereits die Schnipsel hast, wie calculate_1 und calculate_2 usw. können wir es ja so machen ohne einen Thread.

Allerdings hat Dein Programm einen Fehler: Jedesmal wenn der Anwender den Button für "Berechnung" drückt, erzeugst Du einen neuen Frame für den Ladebalken, nämlich self.hintergrund.

Das gehört sich nicht. Wenn Du einen neuen erzeugst, wäre zuerst der alte mit self.hintergrund.destroy() zu zerstötren. Aber das gehört sich auch nicht. Erzeuge ihn einmal und mache ihn am Ende unsichtbar mit self.hintergrund.place_forget(). Der Name hintergrund ist auch nicht besonders aussagekräftig, wenn es sich um eine Fortschrittsanzeige handeln soll.

Was man auf jeden Fall kennen sollte, ist die Methode after. Damit können wir der GUI Zeit geben, um Veränderungen zu zeichnen und dann wieder eine der unsrigen Methoden aufzurufen.

Das wäre dann der Code:

Code: Alles auswählen

import tkinter
import time
 
 
class Berechnungsprogramm:
    def __init__(self):
        self.master=tkinter.Tk()
        self.master.title("Berechnungsprogramm")
        self.master.resizable(0,0)
        self.frame1()
        self.master.mainloop()
 
    def frame1(self):
        self.mainframe=tkinter.Frame(height=400, width=400, bg="yellow")
        self.button=tkinter.Button(text="Berechnung", command=self.check)
        self.label_1=tkinter.Label(text="", bg="yellow", fg="black", font=("Arial",20))
        self.mainframe.pack()
        self.button.place(x=4, y=370)
        self.label_1.place(x=50, y=50)
 
        # Ladebalken
        self.hintergrund=tkinter.Frame(master=self.mainframe, height=100, width=200, bg="black")
        self.vordergrund=tkinter.Frame(master=self.hintergrund, height=96, width=196, bg="white")
        self.label_2=tkinter.Label(master=self.vordergrund, text="Anzeige", font=("Arial", 14), bg="white", fg="black")
        self.vordergrund.place(x=2, y=2)
        self.label_2.place(x=5, y=5)
 
    def check(self):
        self.button['state'] = 'disabled'
        self.ladebalken()
        self.master.after(10,self.calculate_1) # 10 ms, damit die Zeit zum Zeichnen der Anzeige reicht, bei 1 ms war dieser Frame nur schwarz bei mir
 
    def ladebalken(self):
        # Hier soll nun in meinem eigentlichen Programm ein Frame geöffnet werden und über meinem mainframe liegen.
        # Auf diesem neuen Frame soll eine Progressbar über den Fortschritt der Berechnungen informieren.
        # Simbolisch dafür steht hier einfach nur ein Label mit einem Text.
        self.hintergrund.place(x=100, y=180)
        self.hintergrund.lift()
 
    def calculate_1(self):
        # Hier werden jetzt einige Berechnungen durchgeführt, die ein paar
        # Sekunden in Anspruch nehmen. Deshalb soll eine Progressbar über den
        # Fortschritt informieren.
        # Die Berechnungen sollen hier durch eine einfache (und hier sinnlose)
        # Variablenzuweisung symbolisiert werden:
        sinnlosaktion=0
        time.sleep(3)   # Ich möchte, dass das Programm etwas Zeit benötigt, um komplett ausgeführt werden zu können.
                        # Darum pausiere ich es hier an dieser Stelle.
        self.label_1.config(text="Hallo Welt")
        self.master.after(10,self.calculate_2)
 
    def calculate_2(self):
        # Im eigentlichen Programm gibt es 10 solcher Unterfunktionen die für die Berechnung durchlaufen werden müssen.
        # Ich habe jetzt hier in diesem Beispielprogramm zwei Funktionen stellvertretend niedergeschrieben.
        sinnlosaktion=0
        time.sleep(3)
        self.hintergrund.place_forget()
        self.button['state'] = 'normal'

app=Berechnungsprogramm()
Sirius3
User
Beiträge: 17738
Registriert: Sonntag 21. Oktober 2012, 17:20

@Alfons Mittelmeyer: was soll das wirre Zeug, dass ein Thread viel Verwaltungsaufwand und verlorene Zeit wäre. Bevor Du das merkst, mußt Du schon sehr ungeschickt mit Threads sein. Was Du hier als Lösung präsentierst, ist keine. Durch das Aufrufen von calculate_x durch after ist nichts gewonnen, weil die GUI während des Ausführens einfriert.
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Alfons Mittelmeyer: was soll das wirre Zeug, dass ein Thread viel Verwaltungsaufwand und verlorene Zeit wäre.

Ich glaube nicht, daß Du schon einmal ein Echtzeit Multitasking Betriebssystem für Mobilfunk Basisstationen geschrieben hast. Und sicher willst Du nicht, wenn Du mit dem Handy telefonierst, daß es dann in der Verbindung knackt, weil Threadwechsel stattfinden.
Da gibt es harte Anforderungen, daß so ein Codeschnipsel nur soundsoviel Microsekunden dauern darf, bevor das OS wieder die Kontrolle berkommt. Und ein Threadwechsel dauert zuviele Mikrosekunden, weil da auch noch eine Reihe von Threadspezifischen Variablen kopiert werden müssen. Bei Verwaltungsaufwand meinte ich nicht den für den Anwendungsprogrammierer, sondern den für das Betriebssystem oder in unserem Fall, den für Python intern.
Sirius3 hat geschrieben:Bevor Du das merkst, mußt Du schon sehr ungeschickt mit Threads sein. Was Du hier als Lösung präsentierst, ist keine. Durch das Aufrufen von calculate_x durch after ist nichts gewonnen, weil die GUI während des Ausführens einfriert.
Sie soll doch einfrieren und dabei die Berechnung ausführen und der User soll auf das Ergebnis warten, bis er wieder etwas tun kann. So habe ich es zumindest verstanden.

Wenn es nur wenige Sekunden sind, ist das durchaus akzeptabel. Und wenn es länger dauert, wie etwa bei einer Betriebssystem Installation mit Progressbalken viele Minuten lang, dann wird das auch akzeptiert, oder?
BlackJack

@Alfons Mittelmeyer: Es mag ja sein das Threads nicht die Anforderungen an ein Echtzeit Multitasking Betriebssystem für Mobilfunk Basisstationen erfüllen, das ist aber auch sowas von egal in diesem Zusammenhang, denn auf den Rechnern wird auch niemand eine GUI-Anwendung in Python und Tk/Tcl schreiben. Jedenfalls nicht mit diesen Echtzeitanforderungen.

Nein, ein einfrieren der GUI wird nicht akzeptiert. Es ist ja nicht so dass die GUI einfach ”stehen bleibt” — man kann auch das Fenster nicht mehr schliessen, und wenn Teile des Fensters verdeckt werden, zum Beispiel durch andere Fenster oder weil der Anwender das Fenster teilweise aus dem Desktopbereich verschiebt oder wenn das Fenster minimiert und wieder hergestellt wird, dann sind Teile des Fensters oder das ganze Fenster nicht mehr definiert. Da kann dann Grafikmüll oder eine leere Fläche angezeigt werden. Das finden die meisten Anwender nicht akzeptabel.

Und auch einige Betriebssysteme finden es nicht akzeptabel wenn die Anwendung die GUI-Hauptschleife nicht mehr bedient und informiert den Benutzer das die Anwendung nicht mehr reagiert und fragt nach ob sie gekillt werden soll. Das ist kein ordentliches Verhalten eines Programms. Das tun die Installationsprogramme die ich so kenne auch nicht.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Pykons

Hier etwas zum experimentieren und optimieren. Es ist keine Fortschrittsanzeige integriert. Die Berechnung wird aber in einem Tkinter unabhängigen Thread ausgeführt:

Code: Alles auswählen

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

from functools import partial
import threading
from time import sleep

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

APP_TITLE = "Berechnungsprogramm"
APP_BACK_GND = "yellow"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 400
APP_HEIGHT = 400

QUEUE_SIZE = 10
POLLING_TIME = 500   # Milliseconds

CALCULATION_MODES = ["Berechnung-1", "Berechnung-2", "Berechnung-3"]


class CalculationThread(threading.Thread):
    
    def __init__(self, queue, calculation):
        self.queue = queue
        self.calculation = calculation
        
        threading.Thread.__init__(self)
        self.start()

    def run(self):
        result = self.calculation()    
        self.update_queue(result)
        
    def update_queue(self, message):
        self.queue.put(message)
        self.queue.join()


class Calculations(object):
    
    def __init__(self, parent, queue):
        self.parent = parent
        self.queue = queue
        self.calculation_thread = None
        
        self.calculations_procedures = [
            self.calculation_01,
            self.calculation_02,
            self.calculation_03]
            
    def execute(self, index=None):
        if index == None: return
        
        self.parent.label_var.set(CALCULATION_MODES[index])
        self.parent.resultat_var.set("Bin Beschäftigt!")
        
        if self.calculation_thread == None:
            self.calculation_thread = CalculationThread(
                self.queue, self.calculations_procedures[index])
        
    def calculation_01(self):
        sleep(2.0) # Simulated calculation time (Place here your caculation-01)
        return "Resultat der Berechnung-1"

    def calculation_02(self):
        sleep(2.0) # Simulated calculation time (Place here your caculation-02)
        return "Resultat der Berechnung-2"

    def calculation_03(self):
        sleep(2.0) # Simulated calculation time (Place here your caculation-03)
        return "Resultat der Berechnung-3"

    
class Application(tk.Frame):

    def __init__(self, master):
        self.master = master
        self.master.protocol("WM_DELETE_WINDOW", self.close)
        tk.Frame.__init__(self, master)

        self.label_var = tk.StringVar()
        self.label = tk.Label(self, textvariable=self.label_var, bg=self['bg'],
            fg='blue', font=("Arial",20, 'bold'))
        self.label.pack()
        self.label_var.set("Berechnung")
        
        self.frame_for_results = tk.Frame(self, bg='khaki3')
        self.frame_for_results.pack(fill='both', expand=True, pady=6)

        self.button_frame = tk.Frame(self)
        self.button_frame.pack()
        
        for index, button in enumerate(CALCULATION_MODES):
            tk.Button(self.button_frame, text=button, highlightthicknes=0,
            command=partial(self.button_callback, index)).pack(side='left',
                padx=2)
        
        self.resultat_var = tk.StringVar()
        self.label_resultat = tk.Label(self.frame_for_results,
            textvariable=self.resultat_var, bg=self.frame_for_results['bg'],
            font=("Arial",20))
        self.label_resultat.pack(expand=True)
        self.resultat_var.set("Bin nicht Beschäftigt!")
        
        self.queue = qu.Queue(QUEUE_SIZE)
        self.queue_polling()

        self.calculations = Calculations(self, self.queue)

    def button_callback(self, index):
        print(index)
        self.calculations.execute(index)

    def queue_polling(self):
        if self.queue.qsize():
            try:
                data = self.queue.get()
                self.resultat_var.set(data)
                self.queue.task_done()
                self.calculations.calculation_thread = None
            except qu.Empty:
                pass
        
        self.after(POLLING_TIME, self.queue_polling)
                 
    def close(self):
        print("Application-Shutdown")
        self.master.destroy()
 
    
def main():
    app_win = tk.Tk()
    app_win.title(APP_TITLE)
    app_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    app_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    app_win.resizable(0,0)
    app_win.config(bg=APP_BACK_GND)
    app_win.option_add("*Frame.background", APP_BACK_GND)
    app_win.option_add("*Label.background", APP_BACK_GND)
    
    app = Application(app_win).pack(fill='both', expand=True, padx=6, pady=6)
    
    app_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Gruss wuf :wink:
Take it easy Mates!
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

Sirius3 hat geschrieben:@Pykons: Um also im Hintergrund Berechnungen durchführen zu können, brauchst Du Threads mit all den Schwierigkeiten, die die Kommunikation zwischen Rechenthread und Anzeige mit sich bringt. Ob sich der Aufwand für einen Fortschrittsbalken lohnt, sei Dir selbst überlassen.
Wo sollen, da Schwierigkeiten für die Kommunikation zwischen Thread und GUII sein, Threads sind doch einfach. Schwierig sind dagegen die Codeschnipsel und stimmt, es kann auch Probleme mit der GUI geben, wenn sie zulange dauern. Sekundenbruchteile allerdings machen nichts aus.

@Pykon: Wenn etwas längere Zeit in Ansprich nimmt sollte man Threads nehmen. Man sollte Threads kennen und sie sind auch einfach zu handhaben. Man kann dort ohne Probleme lange brauchen, und wenn man der GUI etwas mitteile will, legt man am Besten die Informaton für die GUI in eine threadsichere Queue. Die GUI pollt in Zeitabständen - ich habe einmal 100 ms gewählt - die Queue, ob etwas für sie da ist und führt das entsprechend aus.

Code: Alles auswählen

import tkinter
import time
import queue
import threading
 
def berechnen_im_thread(queue):
 
    '''
    calculate_1
    '''
    # Hier werden jetzt einige Berechnungen durchgeführt, die ein paar
    # Sekunden in Anspruch nehmen. Deshalb soll eine Progressbar über den
    # Fortschritt informieren.
    # Die Berechnungen sollen hier durch eine einfache (und hier sinnlose)
    # Variablenzuweisung symbolisiert werden:
    sinnlosaktion=0
    time.sleep(3)   # Ich möchte, dass das Programm etwas Zeit benötigt, um komplett ausgeführt werden zu können.
                    # Darum pausiere ich es hier an dieser Stelle.
 
    # Meldung an die GUI, habe ein Tupel gewählt, damit man auch noch zusätzliche Parameter übergeben kann,
    # etwa Prozent für Fortschrittsbalken
    queue.put(('hallo',))
 
    '''
    calculate_2
    '''
    sinnlosaktion=0
    time.sleep(3)   # Ich möchte, dass das Programm etwas Zeit benötigt, um komplett ausgeführt werden zu können.
                    # Darum pausiere ich es hier an dieser Stelle.
 
    # Meldung an die GUI,daß die Berechnung zuende ist
    queue.put(('end',))
   
 
class Berechnungsprogramm:
    def __init__(self):
        self.queue = queue.Queue()
 
        self.master=tkinter.Tk()
        self.master.title("Berechnungsprogramm")
        self.master.resizable(0,0)
        self.frame1()
        self.master.mainloop()
 
 
    def berechnen(self,*parameters):
        # Berechnungsthread starten
        threading.Thread(target=berechnen_im_thread,args=parameters).start()
        self.execute_queue() # und Queue pollen starten
 
    # Meldungen in der Queue ausführen
    def execute_queue(self):
        while not self.queue.empty():
 
            message = self.queue.get()
            msg_id = message[0]
               
            if msg_id == 'hallo':
                self.label_1.config(text="Hallo Welt")
            elif msg_id == 'end':
                self.hintergrund.place_forget()
                self.button['state'] = 'normal'
                return # zurückkehren ohne den poll timer wieder zu starten, denn jetzt ist Ende der Berechnung
 
        # Neuaufruf nach 100 ms
        self.master.after(100,self.execute_queue)
 
 
    def frame1(self):
        self.mainframe=tkinter.Frame(height=400, width=400, bg="yellow")
        self.button=tkinter.Button(text="Berechnung", command=self.check)
        self.label_1=tkinter.Label(text="", bg="yellow", fg="black", font=("Arial",20))
        self.mainframe.pack()
        self.button.place(x=4, y=370)
        self.label_1.place(x=50, y=50)
 
        # Ladebalken
        self.hintergrund=tkinter.Frame(master=self.mainframe, height=100, width=200, bg="black")
        self.vordergrund=tkinter.Frame(master=self.hintergrund, height=96, width=196, bg="white")
        self.label_2=tkinter.Label(master=self.vordergrund, text="Anzeige", font=("Arial", 14), bg="white", fg="black")
        self.vordergrund.place(x=2, y=2)
        self.label_2.place(x=5, y=5)
 
    def check(self):
        self.button['state'] = 'disabled'
        self.ladebalken()
        self.berechnen(self.queue)
 
    def ladebalken(self):
        # Hier soll nun in meinem eigentlichen Programm ein Frame geöffnet werden und über meinem mainframe liegen.
        # Auf diesem neuen Frame soll eine Progressbar über den Fortschritt der Berechnungen informieren.
        # Simbolisch dafür steht hier einfach nur ein Label mit einem Text.
        self.hintergrund.place(x=100, y=180)
        self.hintergrund.lift()
 
 
app=Berechnungsprogramm()
Alfons Mittelmeyer
User
Beiträge: 1715
Registriert: Freitag 31. Juli 2015, 13:34

@Pykon: etwas habe ich nicht korrekt gemacht - Kommentare soll man immer mit # schreiben und nicht das Stringliteral dafür mißbrauchen

Und in Zeile 87 kannst Du auch weitere Parameter für Deine Daten übergeben, sofern Du diese auch bei berechnen_im_thread in Zeile 6 deklarierst. Der Thread soll alle von extern benötigten Daten beim Aufruf als Parameter bekommen und darf sie nicht aus dem GUI Thread nehmen!!!
Pykons
User
Beiträge: 11
Registriert: Dienstag 14. Februar 2017, 09:45

Vielen vielen Dank euch Allen! Ich habe jetzt einen interessanten Ansatz, um meine Idee umzusetzen!
Ich konzentriere mich nun allerdings erstmal darauf, meine elementar wichtigen Dinge abzuschließen und schaue dann, ob noch genug Zeit übrig bleibt, um auch den Ladebalken zu realisieren!

Aber wie gesagt: Danke für eure Hilfe!
Antworten