Modifing tkinter same canvas from multiple thread with Python - python

I'm trying to make et Game of life with tkinter. The matrix of the game is a canvas which every cell is a square (white = dead and green = alive).
I wanted to do some multithreading to avoid a too long process time when the matrix is big. But when I'm trying to modify the square color from the threads the window in not responding and I can't solve this problem. I tried a lot of things like putting a common lock in every thread when they are modifying the canvas but it's not working either.
Does someone have ideas to solve this problem or even why this appends?
Thanks by advance
Here's my code :
import tkinter as tk
import threading
import random
from functools import partial
class MainFrame(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
x_coord = int(self.winfo_screenwidth() / 2) - 600
y_coord = int(self.winfo_screenheight() / 2 - 390)
self.geometry("{}x{}+{}+{}".format(1200, 750, x_coord, y_coord))
"""Graphique elements"""
# Labels
self.labelcountgen = tk.Label(self, text="Generation 0", font=("Arial", 9))
self.labelcountgen.grid(row=0, column=1)
"""Graphique data"""
self.graphiquematrice = tk.Canvas(self, height=740, width=1000, bg='white')
self.windimention = [1200, 750]
self.generation = 100
"""Matrice"""
self.matrice = []
self.firstquarter = []
self.secondquarter = []
self.thirdquarter = []
self.fourthquarter = []
self.newmatrice = []
self.cellids = []
self.dimention = [70, 100]
self.density = 15
self.scale = 10
self.initmatrice()
self.launchtime()
"""Init Methodes"""
def initmatrice(self):
"""
initialisation du premier etat de la matrice
"""
self.dimention = [80, 100]
self.matrice = []
self.cellids = []
self.graphiquematrice.grid(row=1, column=1, rowspan=10)
for line in range(self.dimention[0]):
self.matrice.append([])
self.cellids.append([])
for col in range(self.dimention[1]):
chance = random.randrange(1, 100, 1)
if chance <= self.density:
self.matrice[line].append(1)
self.cellids[line].append(self.graphiquematrice.create_rectangle(col*self.scale, line*self.scale, (col+1)*self.scale, (line+1)*self.scale, outline='black', fill='green'))
else:
self.matrice[line].append(0)
self.cellids[line].append(self.graphiquematrice.create_rectangle(col*self.scale, line*self.scale, (col+1)*self.scale, (line+1)*self.scale, outline='black', fill='white'))
self.graphiquematrice.tag_bind(self.cellids[line][col], '<Button-1>', partial(self.changestateonclick, self.cellids[line][col]))
"""Calcul Next generation"""
def launchtime(self):
for i in range(self.generation):
self.labelcountgen.config(text="Generation " + str(i + 1))
self.evolve()
self.update()
def getneighboor(self, coord):
neighboor = []
for i in range(3):
lineindex = coord[0] + i - 1
if lineindex == -1:
lineindex = self.dimention[0] - 1
elif lineindex == self.dimention[0]:
lineindex = 0
for j in range(3):
colindex = coord[1] + j - 1
if colindex == -1:
colindex = self.dimention[1] - 1
elif colindex == self.dimention[1]:
colindex = 0
if lineindex != coord[0] or colindex != coord[1]:
neighboor.append(self.matrice[lineindex][colindex])
return neighboor
def nextcellstate(self, coord):
state = self.matrice[coord[0]][coord[1]]
neighboor = self.getneighboor(coord)
alive = 0
dead = 0
for one in neighboor:
if one == 0:
dead += 1
else:
alive += 1
if alive == 3:
return 1
elif alive == 2:
return state
else:
return 0
def nextfirstquarterstate(self, quarter, lock):
self.firstquarter = []
start = 0
for line in range(quarter):
self.firstquarter.append([])
for col in range(self.dimention[1]):
self.firstquarter[line].append(self.nextcellstate([line, col]))
with lock:
if self.firstquarter[line][col] == 0:
self.graphiquematrice.itemconfig(self.cellids[line][col], fill='white')
else:
self.graphiquematrice.itemconfig(self.cellids[line][col], fill='green')
def nextsecondquarterstate(self, quarter, lock):
self.secondquarter = []
start = quarter
for line in range(quarter):
self.secondquarter.append([])
for col in range(self.dimention[1]):
self.secondquarter[line].append(self.nextcellstate([line + start, col]))
with lock:
if self.secondquarter[line][col] == 0:
self.graphiquematrice.itemconfig(self.cellids[line][col], fill='white')
else:
self.graphiquematrice.itemconfig(self.cellids[line][col], fill='green')
def nextthirdquarterstate(self, quarter, lock):
self.thirdquarter = []
start = quarter * 2
for line in range(quarter):
self.thirdquarter.append([])
for col in range(self.dimention[1]):
self.thirdquarter[line].append(self.nextcellstate([line + start, col]))
with lock:
if self.thirdquarter[line][col] == 0:
self.graphiquematrice.itemconfig(self.cellids[line + start][col], fill='white')
else:
self.graphiquematrice.itemconfig(self.cellids[line + start][col], fill='green')
def nextfourthquarterstate(self, quarter, lock):
self.fourthquarter = []
start = quarter * 3
for line in range(quarter):
self.fourthquarter.append([])
for col in range(self.dimention[1]):
self.fourthquarter[line].append(self.nextcellstate([start + line, col]))
with lock:
if self.firstquarter[line][col] == 0:
self.graphiquematrice.itemconfig(self.cellids[start + line][col], fill='white')
else:
self.graphiquematrice.itemconfig(self.cellids[start + line][col], fill='green')
def evolve(self):
self.newmatrice = []
threads = []
lock = threading.Lock()
quarter = int(self.dimention[0] / 4) # Division de la matrice en 4 pour reduire le temps de calcul
threads.append(threading.Thread(target=self.nextfirstquarterstate, args=(quarter, lock))) # Premier quart
threads.append(threading.Thread(target=self.nextsecondquarterstate, args=(quarter, lock))) # Deuxieme quart
threads.append(threading.Thread(target=self.nextthirdquarterstate, args=(quarter, lock))) # 3eme quart
threads.append(threading.Thread(target=self.nextfourthquarterstate, args=(quarter, lock))) # 4eme quart
i = 0
for t in threads:
t.setDaemon(True)
try:
t.start() # Lancement des 4 threads
except:
print("Error: not able to lauch thread " + str(i))
i += 1
for t in threads:
t.join() # Attente de la fin de tous les calculs
self.matrice = self.firstquarter + self.secondquarter + self.thirdquarter + self.fourthquarter
"""Binding Methodes"""
def changestateonclick(self, idcell, event):
color = self.graphiquematrice.itemcget(idcell, 'fill')
if color == 'white':
self.graphiquematrice.itemconfig(idcell, fill='green')
else:
self.graphiquematrice.itemconfig(idcell, fill='white')
if __name__ == '__main__':
root = MainFrame()
root.mainloop()

Related

Pyside6 GUI crashes when updating GUI after thread

So basically the title, after threading I try to update the GUI, but it stops responding and closes. I am using qt designer so the GUI itself is in another file. The first code block is where I make the GUI interactive. The second is what will be run in the thread. I really appreciate any help you can provide.
Main thread
class interact(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super(interact, self).__init__( *args, **kwargs)
self.setupUi(self)
self.scaleX = 800
self.scaleY = 800
self.index = 0
self.newIndex = 0
self.translatedFiles = []
self.files = []
self.isClicked = False
self.upload.clicked.connect(self.upload1)#connecting button to self.upload1
self.upload.clicked.connect(self.change1)
self.rightArrow.clicked.connect(self.moveRight) #button
self.leftArrow.clicked.connect(self.moveLeft) #button
self.translate.clicked.connect(self.translate1) #button
self.translate.clicked.connect(self.change)
def upload1(self):
filenames, _ = QFileDialog.getOpenFileNames(
None,
"QFileDialog.getOpenFileNames()",
"",
"Image files (*.jpg *.png)"
)
for file in filenames:
self.files.append(file)
self.showImage()
def moveRight(self):
if self.isClicked == True:
if self.newIndex >= len(self.translatedFiles)-1:
self.newIndex = len(self.translatedFiles)-1
else:
self.newIndex += 1
else:
if self.index >= len(self.files)-1:
self.index = len(self.files)-1
else:
self.index += 1
self.showImage()
def moveLeft(self):
if self.isClicked == True:
if self.newIndex <= 0:
self.newIndex = 0
else:
self.newIndex -= 1
else:
if self.index <= 0:
self.index = 0
else:
self.index -= 1
self.showImage()
def showImage(self):
#actual = QImage(self.files[self.index])
if self.isClicked == True:
im = self.translatedFiles[self.newIndex]
im = im.convert("RGB")
data = im.tobytes("raw","RGB")
qim = QImage(data, im.size[0], im.size[1], QImage.Format_RGB888)
pix = QPixmap(qim)
self.Image.setPixmap(pix)
print("change")
else:
pix = QPixmap(self.files[self.index])
self.Image.setPixmap(pix)
print(self.files[self.index])
print("KC")
def afterThread(self, s):
myarray = np.array(s)
img = im.fromarray(myarray)
self.translatedFiles.append(img)
print("THREAD COMPLETE!")
def change(self):
self.isClicked = True
def change1(self):
self.isClicked = False
def translate1(self):
self.thread = QThread()
self.worker = Translate(self.files[self.index])
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.finished.connect(self.afterThread)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.thread.finished.connect(self.showImage)
self.thread.start()
if __name__ == "__main__":
import sys
app =QtWidgets.QApplication(sys.argv)
w = interact()
w.show()
sys.exit(app.exec())
Thread:
class Translate(QObject):
finished = Signal(list)
def __init__(self, img):
super(Translate, self).__init__()
self.img1 = cv2.imread(img)
self.image = cv2.cvtColor(self.img1, cv2.COLOR_BGR2RGB)
self.mocr = MangaOcr()
# self.run()
def chronos(func):
def get_time(*args, **kawrgs):
start = time.time()
x = func(*args, **kawrgs)
end = time.time()
print("{} took {} seconds".format(func, (end-start)))
return x
return get_time
#chronos
def get_text(self, image):
reader = easyocr.Reader(['ja'], gpu=False)
result = reader.readtext(image, paragraph=True)
myDict = {}
for (bbox, text) in result:
(tl, tr, br, bl) = bbox
tl = (int(tl[0]), int(tl[1]))
tr = (int(tr[0]), int(tr[1]))
br = (int(br[0]), int(br[1]))
bl = (int(bl[0]), int(bl[1]))
myDict[str(bl)] = ([tl , br ])
return myDict
#chronos
def get_japanese(self, diction):
newList = {}
et = {}
ts = {}
directory = os.getcwd()+'\MangaTranslation\cropText'
for x in diction:
cropped_image = self.image[diction[x][0][1]:diction[x][1][1], diction[x][0][0]:diction[x][1][0]]
if not(os.path.exists(os.path.join(directory, str(x)+'.jpg'))):
cv2.imwrite(os.path.join(directory, str(x)+'.jpg'), cropped_image)
et[str(x)] = os.path.join(directory, str(x)+'.jpg')
for root, dirs, files in os.walk(directory):
for x in files:
try:
img = Image.open((root+"\\"+ x).strip())
text = self.mocr(img)
ts[(root+"\\"+ x).strip()] = text
except:
print("not pic")
mg = et.items()
tg = ts.items()
for coor, direct in mg:
for dir1, jap in tg:
if direct == dir1:
newList[coor] = jap
return newList
#chronos
def translate(self, original):
for jap in original:
original[jap] = str(ts.bing(original[jap]))
return original
def segment(self, list1):
for line in list1:
newL= list(str(list1[line]))
s = ''
count = 0
for x in range(len(newL)):
if newL[x] == " ":
count += 1
if count == 3:
newL[x] = "\n"
count = 0
s += newL[x]
list1[line] = s
return list1
def write(self, img, dict1, list1):
fontSize = .5
# if img.shape > (1200, 851, 3):
# fontSize *= 10
for value in dict1:
cv2.rectangle(img, dict1[value][0], dict1[value][1], (0, 255, 255), 2)
image = add_text_to_image(
img,
list1[value],
font_color_rgb=(255, 0, 0),
top_left_xy=(dict1[value][0][0], dict1[value][1][1]),
font_scale= fontSize,
font_face=cv2.FONT_HERSHEY_DUPLEX
)
return image
# plt.rcParams['figure.figsize'] = (16,16)
# plt.imshow(image)
# plt.show()
def run(self):
gotten_text = self.get_text(self.image)
finalText = self.get_japanese(gotten_text)
newList = self.translate(finalText)
addNewLine = self.segment(newList)
final = self.write(self.image, gotten_text, addNewLine)
self.finished.emit(final)
When I run the program, both in the IDE and terminal, I don't get any errors, I just get:
<function Translate.get_text at 0x0000013C5D880B80> took 10.577515602111816 seconds
<function Translate.get_japanese at 0x0000013C5DA03E50> took 6.2078752517700195 seconds
<function Translate.translate at 0x0000013C5DA03EE0> took 8.287482023239136 seconds
THREAD COMPLETE!

Multiprocessing in class isn't using full cpu range

I have a Program which, on start, opens a GUI which allows the user to select a raw file which then is getting read in and a function is called to calculate some stuff which is then getting saved in a pickle file.
Depending on the size of the file this might take up to 12 or more hours. (heavy calculations)
So my approach was to allow the Program to run the calculations in different processes with the multiprocessing module. But it seems like I am not using the full range of the CPU. When I start the first process the CPU utilization goes from like 4-5% up to around 20% but when I start the second process it stays at around 20%
The code is to big to post it here so im trying to explain it as good as possible
class main():
def __init__(self,master):
self.processes= {'1': 0, '2' :0, '3' :0,'4':0,'5':0,'6':0}
self.master = master
self.master.title("Framework")
self.master.minsize(1450, 650)
self.master.maxsize(1450,650)
style = ttk.Style()
style.theme_use('clam')
style.configure('Custom.TButton',background='#94FDFA')
self.Box4 = Entry(self.master)
self.text = Text(self.master)
self.scroll = Scrollbar(self.master, command=self.text.yview)
self.text.configure(yscrollcommand=self.scroll.set)
self.text.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text.place( x = 450, y =80,bordermode="inside", width=300,height=250)
self.scroll.place(x=750,y=80, height= 250)
self.text2 = Text(self.master)
self.scroll2 = Scrollbar(self.master, command=self.text.yview)
self.text2.configure(yscrollcommand=self.scroll2.set)
self.text2.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text2.place( x = 775, y =80,bordermode="inside", width=300,height=250)
self.scroll2.place(x=1075,y=80, height= 250)
self.text3 = Text(self.master)
self.scroll3 = Scrollbar(self.master, command=self.text.yview)
self.text3.configure(yscrollcommand=self.scroll3.set)
self.text3.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text3.place( x = 1100, y =80,bordermode="inside", width=300,height=250)
self.scroll3.place(x=1400,y=80, height= 250)
self.text4 = Text(self.master)
self.scroll4 = Scrollbar(self.master, command=self.text.yview)
self.text4.configure(yscrollcommand=self.scroll4.set)
self.text4.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text4.place( x = 450, y =370,bordermode="inside", width=300,height=250)
self.scroll4.place(x=750,y=370, height= 250)
self.text5 = Text(self.master)
self.scroll5 = Scrollbar(self.master, command=self.text.yview)
self.text5.configure(yscrollcommand=self.scroll5.set)
self.text5.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text5.place( x = 775, y =370,bordermode="inside", width=300,height=250)
self.scroll5.place(x=1075,y=370, height= 250)
self.text6 = Text(self.master)
self.scroll6 = Scrollbar(self.master, command=self.text.yview)
self.text6.configure(yscrollcommand=self.scroll6.set)
self.text6.tag_configure('bold_italics', font=('Verdana', 12, 'bold', 'italic'))
self.text6.place( x = 1100, y =370,bordermode="inside", width=300,height=250)
self.scroll6.place(x=1400,y=370, height= 250)
self.Box4.place( x = 10, y = 10,bordermode="inside", width=820,height=35)
self.b1 = ttk.Button(self.master,text = "Folder", command=self.select_folder)
self.b1.place(x=850, y=10)
self.b2 = ttk.Button(self.master, text="run", command=self.go)
self.b2.place(x=20, y=600)
self.master.geometry('%dx%d+%d+%d' % (950, 400, 20, 20))
def update(self, tid):
try:
if tid == self.processes['2']:
self.text.insert(END, (self.text1 + '\n'))
self.text.see("end")
except IndexError:
return
except AttributeError:
return
try:
if tid == self.processes['1']:
self.text2.insert(END, (self.text1 + '\n'))
self.text2.see("end")
except IndexError:
return
except AttributeError:
return
try:
if tid == self.processes['3']:
self.text3.insert(END, (self.text1 + '\n'))
self.text3.see("end")
except IndexError:
return
except AttributeError:
return
try:
if tid == self.processes['4']:
self.text4.insert(END, (self.text1 + '\n'))
self.text4.see("end")
except IndexError:
return
except AttributeError:
return
try:
if tid == self.processes['5']:
self.text5.insert(END, (self.text1 + '\n'))
self.text5.see("end")
except IndexError:
return
except AttributeError:
return
try:
if tid == self.processes['6']:
self.text6.insert(END, (self.text1 + '\n'))
self.text6.see("end")
except IndexError:
return
except AttributeError:
return
def select_folder(self):
mas = tk.Toplevel()
mas.withdraw()
dir_path = filedialog.askdirectory()
self.Box4.insert(0,str(dir_path))
self.dir_path = dir_path
def go(self):
Thread(target = self.spawn).start()
def spawn(self):
while True:
if self.processes['1'] == 0:
proc = 1
p = multiprocessing.Process(target=self.run(proc))
p.start()
p.join()
break
if self.processes['2'] == 0:
proc = 2
p2 = multiprocessing.Process(target=self.run(proc))
p2.start()
p2.join()
break
if self.processes['3'] == 0:
proc = 3
p3 = multiprocessing.Process(target=self.run(proc))
p3.start()
p3.join()
break
if self.processes['4'] == 0:
proc = 4
p4 = multiprocessing.Process(target=self.run(proc))
p4.start()
p4.join()
break
if self.processes['5'] == 0:
proc = 5
p5 = multiprocessing.Process(target=self.run(proc))
p5.start()
p5.join()
break
if self.processes['6'] == 0:
proc = 6
p6 = multiprocessing.Process(target=self.run(proc))
p6.start()
p6.join()
break
def run(self, process):
while True:
if self.processes['1'] == 0:
self.processes['1'] = process
self.text.delete('1.0', END)
me = 1
break
if self.processes['2'] == 0:
self.processes['2'] = process
self.text2.delete('1.0', END)
me = 2
break
if self.processes['3'] == 0:
self.processes['3'] = process
self.text3.delete('1.0', END)
me = 3
break
if self.processes['4'] == 0:
self.processes['4'] = process
self.text4.delete('1.0', END)
me = 4
break
if self.processes['5'] == 0:
self.processes['5'] = process
self.text5.delete('1.0', END)
me = 5
break
if self.processes['6'] == 0:
self.processes['6'] = process
self.text6.delete('1.0', END)
me = 6
break
else:
return
time.sleep(2)
self.text1 = "done 1/10"
self.update(me)
time.sleep(5)
self.text1 = "done 2/10"
self.update(me)
time.sleep(3)
self.text1 = "done 3/10"
self.update(me)
time.sleep(8)
self.text1 = "done 4/10"
self.update(me)
time.sleep(2)
self.text1 = "done 5/10"
self.update(me)
if me== 1:
self.processes['1'] = 0
if me== 2:
self.processes['2'] = 0
if me== 3:
self.processes['3'] = 0
if me== 4:
self.processes['4'] = 0
if me== 5:
self.processes['5'] = 0
if me== 6:
self.processes['6'] = 0
if __name__ == '__main__':
master = tk.Tk()
ma = main(master)
master.mainloop()
I'm new to multiprocessing so if you have any good advice for me on how to do it right I would be really thankful.

Python Tkinter & matplotlib - RuntimeError

Okay so I wrote this code...
#!/usr/bin/env
import sys
import time
import subprocess
from Tkinter import *
import numpy
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import matplotlib
import matplotlib.pyplot as plt
import threading
CDatei = subprocess.Popen("/home/pi/meinc++/Spi")
print("Hallo")
i = 0
x = 0
def GetValue():
with open("/home/pi/meinc++/BeispielDatei.txt","r") as Datei:
for line in Datei:
time.sleep(0.01)
return line
def WithoutNull(input):
ReturnValue = input
while ReturnValue is None:
ReturnValue = GetValue()
return ReturnValue
def UebergabeWert():
while x == 0:
WholeString = WithoutNull(GetValue())
StringVar, DatumVar = WholeString.strip().split(' - ')
IntStringVar = [int(v) for v in StringVar.split()]
return IntStringVar, DatumVar
def MinutenWert():
Maximum = 0
Minimum = 0
i = 0
LaengeArray = 0
Multiplikator = 10000
ArrayValue = [-999999]*Multiplikator
AlteZeit = time.time()
while 1:
CompleteValue, Trash = UebergabeWert()
ArrayValue[i] = CompleteValue[0]
i = i + 1
ArrayFilter = filter(lambda c: c != -999999,ArrayValue)
ArraySumme = numpy.sum(ArrayFilter)
LaengeArray = len(ArrayFilter)
Mittelwert = ArraySumme/LaengeArray
ArraySortierung = sorted(ArrayFilter)
Maximum = ArraySortierung[LaengeArray-1]
Minimum = ArraySortierung[0]
NeueZeit = time.time()
if NeueZeit-AlteZeit >= 60:
AlteZeit = time.time()
ArrayValue[i:Multiplikator] = [-999999]*(Multiplikator-i)
i = 0
yield Mittelwert
yield Maximum
yield Minimum
yield LaengeArray
yield ArrayFilter
def UebergabeTkinter():
while 1:
Mittelwert = next(MinutenWertYield)
Maximum = next(MinutenWertYield)
Minimum = next(MinutenWertYield)
LaengeArray = next(MinutenWertYield)
ArrayFilter = next(MinutenWertYield)
CompleteValue, DatumVar = UebergabeWert()
Variable1.set(CompleteValue[0])
Variable2.set(CompleteValue[1])
Variable3.set(CompleteValue[2])
Variable4.set(CompleteValue[3])
VariableMittelwert.set(Mittelwert)
VariableMaximum.set(Maximum)
VariableMinimum.set(Minimum)
t = threading.Thread(target = Grafik)
t.start()
root.update()
def Grafik():
GrafikAnfang = time.time()
Array = 0
ArrayGrafik = [0]*20
GrafikEnde = 1
while 1:
CompleteValue, DatumVar = UebergabeWert()
ArrayGrafik[Array] = CompleteValue[0]
LaengeArrayGrafik = len(ArrayGrafik)
fig = Figure(figsize = (3, 3))
axis = fig.add_subplot(111)
axis.legend()
axis.grid()
canvas = FigureCanvasTkAgg(fig, master = root)
canvas.get_tk_widget().grid(row=10,column=0,rowspan=2,columnspan=2)
LinienBreite = numpy.linspace(1,LaengeArrayGrafik,LaengeArrayGrafik)
axis.plot(LinienBreite,ArrayGrafik,'b-')
axis.set_xticks(LinienBreite)
DatumArray = [DatumVar]
axis.set_xticklabels(DatumArray)
canvas.draw()
fig.clear()
print Array
if GrafikEnde-GrafikAnfang < 600:
Array = Array + 1
GrafikEnde = time.time()
if GrafikEnde-GrafikAnfang >= 600:
del ArrayGrafik[0]
def Exit():
root.destroy()
return
try:
MinutenWertYield = MinutenWert()
root = Tk()
Leiste = Menu(root)
root.config(menu = Leiste)
DateiMenu = Menu(Leiste)
Leiste.add_cascade(label = "datei", menu = DateiMenu)
DateiMenu.add_command(label = "Exit", command = Exit)
EditMenu = Menu(Leiste)
Leiste.add_cascade(label = "edit", menu = EditMenu)
Variable1 = IntVar()
Variable2 = IntVar()
Variable3 = IntVar()
Variable4 = IntVar()
VariableMittelwert = IntVar()
VariableMaximum = IntVar()
VariableMinimum = IntVar()
Ausgang = 0
for column in range(0,8,2):
String1 = "Ausgang "
String1 += `Ausgang`
Ausgang = Ausgang + 1
Label(text = String1).grid(row=0,column=column)
Ausgang = 0
for column in range(0,8,2):
String1 = "Der Wert von "
String2 = " ist: "
String1 += `Ausgang`
Ausgang = Ausgang + 1
String3 = String1+String2
Label(text = String3).grid(row=2,column=column)
Label(text = "Der Mittelwert ist: ").grid(row=4,column=0)
Label(text = "Das Maximum ist: ").grid(row=5,column=0)
Label(text = "Das Mimimum ist: ").grid(row=6,column=0)
Label1 = Label(root, textvariable = Variable1)
Label1.grid(row = 2, column = 1)
Label2 = Label(root, textvariable = Variable2)
Label2.grid(row = 2, column = 3)
Label3 = Label(root, textvariable = Variable3)
Label3.grid(row = 2, column = 5)
Label4 = Label(root, textvariable = Variable4)
Label4.grid(row = 2, column = 7)
LabelMittelwert = Label(root, textvariable = VariableMittelwert)
LabelMittelwert.grid(row = 4, column = 1)
LabelMaximum = Label(root, textvariable = VariableMaximum)
LabelMaximum.grid(row = 5, column = 1)
LabelMinimum = Label(root, textvariable = VariableMinimum)
LabelMinimum.grid(row = 6, column = 1)
UebergabeTkinter()
print "Hallo"
root.mainloop()
except KeyboardInterrupt:
CDatei.kill()
root.quit()
root.destroy()
and when i run it, it says "RuntimeError: main thread is not in the main loop".
Short explanation of the code: It's a code to read out sensor data from a text file -
GetValue().
If the Data is Null it'll read out again - WithoutNull().
The Data is then splitted into data and timestamp (cause it has the format val1, val2, val3, val4, time) - UebergabeWert.
Then the maxima, minima and average of the data will be measured - MinutenWert()
After this, the values are set as labels and go their way into Tkinter - UebergabeTkinter()
The Tkinter build is mainly in Try:
What I wanted to do there, is to implement a graph to Tkinter, but because of the fast changing values it got tremendously slow so i decided to put the graph build in a thread and run it parallel to Tkinter. Unfortunately, it doesn't seem to work and I don't know why
Any suggestions?

How to make a button in a game class with tkinter

I have been trying to make a button in a class with tkinter, but the button doesn't appear. The rest of the game is fine. I is just when i try to add a quit button in the game class it doesn't appear. I am using python 3.4.3 . I am make a game that you pop bubbles with a submarine. I have tried self.button_quit = tkinter.Button(window, text="Quit") and this is the class code:
class Game():
height = 500
width = 800
mid_x = width / 2
mid_y = height / 2
bonus_score = 700
bubble_chance = 10
gap = 100
time_limit = 30
speed = 0.01
def __init__(self):
self.score = 0
self.bonus = 0
self.window = tkinter.Tk()
self.window.title('Bubble Blaster')
self.canvas = tkinter.Canvas(self.window, width=self.width,
height=self.height, bg='darkblue')
self.end = time.time() + self.time_limit
Text(self.canvas,50,30,'TIME')
Text(self.canvas,150,30,'SCORE')
self.gui_score = Text(self.canvas,150,50)
self.gui_time = Text(self.canvas,50,50)
self.canvas.pack()
self.bubbles = list()
self.ship = Ship(self.canvas)
self.ship.move(self.mid_x, self.mid_y)
def coords_of(cid):
pos = c.coords(cid)
x = (pos[0] + pos[2]) / 2
y = (pos[1] + pos[3]) / 2
return x, y
def create_bubble(self):
x = self.width + self.gap
y = random.randint(0,self.height)
self.bubbles.append(Bubble(self.canvas,x,y))
def move_bubbles(self):
for bubble in self.bubbles:
bubble.move(-bubble.speed,0)
def destroy_bubble(self,bubble):
self.bubbles.remove(bubble)
bubble.destroy()
def clean_up_bubbles(self):
for bubble in self.bubbles:
if bubble.x < -self.gap:
self.destroy_bubble(bubble)
def buttons(self):
self.button1 = tkinter.Button(window, text="Quit")
self.button1.tkinter.pack()
def run(self):
while time.time() < self.end:
if random.randint(1, self.bubble_chance) == 1:
self.create_bubble()
self.move_bubbles()
self.clean_up_bubbles()
self.score += self.ship_bubble_collision()
if (int(self.score / self.bonus_score)) > self.bonus:
self.bonus += 1
self.end += self.time_limit
self.time_left = int(self.end - time.time())
self.update_gui()
self.window.update()
self.ship.step()
time.sleep(self.speed)
Text(self.canvas,self.mid_x, self.mid_y,'GAME OVER',
font=('Helvetica',30))
Text(self.canvas,self.mid_x, self.mid_y + 30,
'Score ' + str(self.score))
Text(self.canvas,self.mid_x, self.mid_y + 45,'Bonus Time ' +
str(self.bonus * self.time_limit))
input()
def distance(self,x1,y1,x2,y2):
return math.sqrt((x2-x1)**2+(y2-y1)**2)
def ship_bubble_collision(self):
points = 0
for bubble in self.bubbles:
distance = self.distance(self.ship.x,self.ship.y,\
bubble.x,bubble.y)
boundary = self.ship.radius + bubble.radius
if distance < boundary:
points += bubble.radius + bubble.speed
self.destroy_bubble(bubble)
return points
def update_gui(self):
self.gui_score.update(str(self.score))
self.gui_time.update(str(self.time_left))
if __name__ == '__main__':
Game().run()
Add
buttons()
Where you need it to be called. Buttons can't appear without being called!
If you need more info on def, click here.
Also for future questions, please elaborate on your question more. It is hard to tell exactly what you are asking.

Improving tkinter.ttk code

I am a fairly novice programmer and through coffee, google, and an immense loss of hair and fingernails have managed to write a very messy code. I am asking anyone to help me simplify the code if possible.
from tkinter import ttk
from tkinter import *
from tkinter.ttk import *
one = 0
why = 'Total Number: {}'
no = 0
clack = 0
click = 'Clicks: {}'
s = ttk.Style()
s.theme_use('clam')
s.configure('red.Vertical.TProgressbar', foreground = 'red', background = 'red')
s.configure('green.Vertical.TProgressbar', foreground = 'green', background = 'green')
s.configure('TButton', relief = 'groove')
def iround(x):
y = round(x) - .5
return int(y) + (y > 0)
class Application(ttk.Frame):
def __init__(self, master = None):
ttk.Frame.__init__(self, master)
self.grid()
self.createWidgets()
def Number(self):
global one
cost = 10*(self.w['to'])
if self.number['text'] == "Make Number go up":
self.number['text'] = one
if iround(self.w.get()) == 0:
one += 1
else:
one += iround(self.w.get())
self.number['text'] = one
if self.number['text'] >= cost:
self.buy['state'] = 'normal'
else:
self.buy['state'] = 'disabled'
self.number['text'] >= cost
self.progress['value'] = one
if self.number['text'] >= cost:
self.progress['style'] = 'red.Vertical.TProgressbar'
else:
self.progress['style'] = 'green.Vertical.TProgressbar'
def Buy(self):
global one
self.w['to'] += 1
cost = 10*(self.w['to'])
one = self.number['text'] = (one + 10 - cost)
self.buy['text'] = ('+1 to slider | Cost: {}'.format(cost))
if self.number['text'] < (cost):
self.buy['state'] = 'disabled'
self.progress['value'] = one
self.progress['maximum'] += 10
if self.number['text'] >= cost:
self.progress['style'] = 'red.Vertical.TProgressbar'
else:
self.progress['style'] = 'green.Vertical.TProgressbar'
def scaleValue(self, event):
self.v['text'] = 'Slider Bonus + ' + str(iround(self.w.get()))
def clicks(self, event):
global click
global clack
if self.Clicks['text'] == 'Clicks: 0':
clack += 1
self.Clicks['text'] = click.format(clack)
self.Clicks['text'] = click.format(clack)
clack += 1
def NumberVal(self, event):
global why
global no
if self.fun['text'] == "Total Number: 0":
self.fun['text'] = why.format(no)
if iround(self.w.get()) == 0:
no += 1
else:
no += iround(self.w.get())
self.fun['text'] = why.format(no)
def createWidgets(self):
self.number = Button(self, text = 'Make number go up', command = self.Number, width = 20, style = 'TButton')
self.number.grid(row = 1, column = 1)
self.number.bind('<ButtonRelease>', self.clicks, add = '+')
self.number.bind('<ButtonRelease>', self.NumberVal, add = '+')
self.buy = Button(self, text = '+1 to Slider | Cost: 10', command = self.Buy, width = 20, style = 'TButton')
self.buy.grid(row = 2, column = 1)
self.buy.config(state = 'disabled')
self.v = Label(self, text = 'Slider Bonus + 0', width = 20, anchor = 'center')
self.v.grid(row = 3, column = 3)
self.w = Scale(self, from_ = 0, to = 1, orient = 'horizontal')
self.w.grid(row = 3, column = 1)
self.w.bind('<Motion>', self.scaleValue)
self.progress = Progressbar(self, value = 0, orient = 'vertical', maximum = 10, mode = 'determinate')
self.progress.grid(row = 1, rowspan = 5, column = 2)
self.Clicks = Label(self, text = 'Clicks: 0', width = 20, anchor = 'center')
self.Clicks.grid(row = 1, column = 3)
self.fun = Label(self, text = 'Total Number: 0', width = 20, anchor = 'center')
self.fun.grid(row = 2, column = 3)
app = Application()
app.master.title('Number')
app.mainloop()

Categories

Resources