Как вызвать функцию из функции модуля верхнего уровня? - PullRequest
0 голосов
/ 14 июля 2020

Я Python noob и хочу разработать приложение windows с поддержкой многопроцессорности. Я нашел здесь пример: http://zetcode.com/articles/tkinterlongruntask/. Но теперь моя проблема в том, что я не могу обновить прокручиваемый текст из метода generatePI, который является функцией модуля верхнего уровня.

Может ли кто-нибудь из вас, ребята, дать мне решение или указать мне направо направление?

Полный код:

from tkinter import (Tk, BOTH, Text, E, W, S, N, END, 
NORMAL, DISABLED, StringVar)
from tkinter.ttk import Frame, Label, Button, Progressbar, Entry
from tkinter import scrolledtext

from multiprocessing import Process, Manager, Queue
from queue import Empty
from decimal import Decimal, getcontext


DELAY1 = 80
DELAY2 = 20

# Queue must be global
q = Queue()

class Example(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent, name="frame")   
             
        self.parent = parent
        self.initUI()
            
    
    def initUI(self):
  
        self.parent.title("Pi computation")
        self.pack(fill=BOTH, expand=True)
    
        self.grid_columnconfigure(4, weight=1)
        self.grid_rowconfigure(3, weight=1)
    
        lbl1 = Label(self, text="Digits:")
        lbl1.grid(row=0, column=0, sticky=E, padx=10, pady=10)
    
        self.ent1 = Entry(self, width=10)
        self.ent1.insert(END, "4000")
        self.ent1.grid(row=0, column=1, sticky=W)
    
        lbl2 = Label(self, text="Accuracy:")
        lbl2.grid(row=0, column=2, sticky=E, padx=10, pady=10)

        self.ent2 = Entry(self, width=10)
        self.ent2.insert(END, "100")
        self.ent2.grid(row=0, column=3, sticky=W)        
    
        self.startBtn = Button(self, text="Start", 
            command=self.onStart)
        self.startBtn.grid(row=1, column=0, padx=10, pady=5, sticky=W)
    
        self.pbar = Progressbar(self, mode='indeterminate')        
        self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E)     
    
        self.txt = scrolledtext.ScrolledText(self)  
        self.txt.grid(row=2, column=0, rowspan=4, padx=10, pady=5,
        columnspan=5, sticky=E+W+S+N)
   
    
    def onStart(self):
    
        self.startBtn.config(state=DISABLED)
        self.txt.delete("1.0", END)
    
        digits = int(self.ent1.get())
        accuracy = int(self.ent2.get())
            
        self.p1 = Process(target=generatePi, args=(q, digits, accuracy))
        self.p1.start()
        self.pbar.start(DELAY2)
        self.after(DELAY1, self.onGetValue)
    
   
    def onGetValue(self):
    
        if (self.p1.is_alive()):
        
            self.after(DELAY1, self.onGetValue)
            return
        else:    
    
           try:

               self.txt.insert('end', q.get(0))
               self.txt.insert('end', "\n")
               self.pbar.stop()
               self.startBtn.config(state=NORMAL)

           except Empty:
               print("queue is empty")
        
# Generate function must be a top-level module funtion            
def generatePi(q, digs, acc):

   getcontext().prec = digs

   pi = Decimal(0)
   k = 0
   n = acc
    
   while k < n:
        pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1)) - \
            (Decimal(2)/(8*k+4)) - (Decimal(1)/(8*k+5))- \
            (Decimal(1)/(8*k+6)))
        k += 1

   q.put(pi)


def main():  

    root = Tk()
    root.geometry("400x350+300+300")
    app = Example(root)
    root.mainloop()  


if __name__ == '__main__':
    main()  

PS: кредит на zetcode.com

...