#!/usr/bin/env python3 GUI_WIN = 0 GUI_LINUX = 1 import sys if sys.platform == 'win32': GUI = GUI_WIN else: GUI = GUI_LINUX 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 if GUI == GUI_WIN: from multiprocessing import Process, Manager, Queue, Value from queue import Empty else: from multiprocessing import Queue, Process import queue from decimal import Decimal, getcontext from time import sleep DELAY1 = 20 DELAY2 = 20 if GUI == GUI_WIN: # Queue must be global q = Queue() class commonUI(Frame): def __init__(self, parent): Frame.__init__(self, parent) self.parent = parent self.initUI() def initUI(self): self.val = Value('i', 0) self.dig = Value('i', 4000) self.acc = Value('i', 100) 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, self.dig.value) 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, self.acc.value) 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='determinate') self.pbar.grid(row=1, column=1, columnspan=3, sticky=W+E) self.pbar.config(value=0, maximum=self.dig.value) 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.after(DELAY1, self.onGetValue) def onGetValue(self): if (self.p1.is_alive()): self.val.value += 1000 self.update_pbar() self.after(DELAY1, self.onGetValue) return else: try: self.txt.insert('end', q.get(0)) self.txt.insert('end', "\n") self.startBtn.config(state=NORMAL) except Empty: print("queue is empty") def update_pbar(self): self.pbar.config(value=self.val.value) class win_Example(Frame): def __init__(self, parent): Frame.__init__(self, parent, name="frame") commonUI(parent) if GUI == GUI_WIN: # 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) time.sleep(1) class linux_Example(Frame): def __init__(self, parent, q): Frame.__init__(self, parent) self.queue = q commonUI(parent) def generatePi(self, queue): getcontext().prec = self.digits pi = Decimal(0) k = 0 n = self.accuracy 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 print (self.p1.is_alive()) queue.put(pi) print("end") def main(): if GUI == GUI_LINUX: q = Queue() root = Tk() root.geometry("400x350+300+300") app = win_Example(root) if GUI == GUI_WIN else linux_Example(root) root.mainloop() if __name__ == '__main__': main()