Tkinter & Threads - Exception: out of stack space (infinite loop?) - python

We implemented a distributed chat, which is using a Tkinter GUI. As I updated my system to Fedora18 Im getting exceptions when calling a Tkinter event, almost the same as described here:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in bootstrap_inner self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run self.target(*self.__args, **self.__kwargs)
File "/hachat/peer.py", line 156, in startRecvLoop
self.processMessage(msg, addr)
File "/hachat/peer.py", line 222, in processMessage
self.gui.receive(msg)
File "/hachat/gui.py", line 74, in receive
self.textfenster.insert(END,msg.name+": "+msg.text+'\n')
File "/usr/lib64/python2.7/lib-tk/Tkinter.py", line 2986, in insert
self.tk.call((self._w, 'insert', index, chars) + args)
TclError: out of stack space (infinite loop?)
Here is a snipped out of the gui-class:
import Tkinter
import ScrolledText
import tkMessageBox
import tkSimpleDialog
import threading
class gui(object):
def __init__(self, parent):
self.root = Tkinter.Tk()
self.textfenster = ScrolledText.ScrolledText(self.fpopup,width=90,height=24,background='white')
self.textfenster.pack(fill=Tkinter.BOTH, expand=Tkinter.YES)
def run(self):
self.guiRunThread = threading.Thread(target=self.root.mainloop())
self.guiRunThread.daemon = True
self.guiRunThread.start()
def receive(self,msg):
self.textfenster.insert(Tkinter.END,msg.name+": "+msg.text+'\n')
self.textfenster.see(Tkinter.END)
The Exception appears only on my system, the reason seems to be that tk was not compiled with support for threads. I have to get rid of this Exeption - as the program is distributed it needs to run on different systems. So Im asking for how to get rid of this exception as well as an hint to get tk for supporting threads.
Im using Python version is 2.7.3, Tcl/Tk version 8.5. import Tkinter; Tkinter.Tk().tk.eval("puts $tcl_platform(threaded)") is giving back a Exception as well.

I solved the problem with Queues to communicate with Tk. See Mutli-threading python with Tkinter for an example!

This one works:
from Tkinter import *
from ScrolledText import ScrolledText
from threading import Thread
scrolled = None
def start():
global scrolled
root = Tk()
scrolled = ScrolledText(root)
scrolled.pack(fill=BOTH, expand=YES)
return root
Thread(target=start().mainloop).start()
print scrolled.get(0.0, END)

Related

I'm trying to make an exit button for the page and for some reason it has error and i don't know how to solve it

I am trying to make an exit button with the code
I do import tkinter* in here
from tkinter import*
from tkinter import ttk
from PIL import Image,ImageTk
import os
def iExit(self):
self.iExit=tkinter.askyesno("Face Recognition","Are you sure you want to exit?")
if self.iExit >0:
self.root.destroy()
else:
return
and I got the error
I know that I cant put tkinter inside the code but i don't know how to solve it. The error that I am getting is here
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\user\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "c:\Users\user\Desktop\FYP\Facial_Recognition system\Main.py", line 148, in iExit
self.iExit=tkinter.askyesno("Face Recognition","Are you sure you want to exit?")
^^^^^^^
NameError: name 'tkinter' is not defined
askyesno is defined in the tkinter.messagebox module. Import it from there:
from tkinter.messagebox import askyesno

Tkinter gives no attribute 'getvar' nor 'eval' error

My code stopped working quite literally overnight, due to an issue with Tkinter.
I'm using PySimpleGui for my project, which was working the previous day.
When I run my program it showed the bellow error:
File "E:/Projekty Python/dcs_assistant/gui_and_video.py", line 1, in <module>
import PySimpleGUI as sg
File "C:\Users\pawni\Miniconda3\envs\dcs_assistant\lib\site-packages\PySimpleGUI\__init__.py", line 2, in <module>
from .PySimpleGUI import *
File "C:\Users\pawni\Miniconda3\envs\dcs_assistant\lib\site-packages\PySimpleGUI\PySimpleGUI.py", line 125, in <module>
tclversion_detailed = tkinter.Tcl().eval('info patchlevel')
File "C:\Users\pawni\Miniconda3\envs\dcs_assistant\lib\tkinter\__init__.py", line 2354, in __getattr__
return getattr(self.tk, attr)
AttributeError: module '_tkinter' has no attribute 'eval'
Process finished with exit code 1
Line 125 is this:
tclversion_detailed = tkinter.Tcl().eval('info patchlevel')
This, as per Tkinter documentation, should simply return the version of Tkinter library (https://tkdocs.com/tutorial/install.html).
When I ran a dummy program using just Tkinter to test if Tkinter alone works. I got another error:
Traceback (most recent call last):
File "E:/Projekty Python/dcs_assistant/test.py", line 3, in <module>
tk = tkinter.Tk()
File "C:\Users\pawni\Miniconda3\envs\dcs_assistant\lib\tkinter\__init__.py", line 2272, in __init__
self._loadtk()
File "C:\Users\pawni\Miniconda3\envs\dcs_assistant\lib\tkinter\__init__.py", line 2286, in _loadtk
tk_version = self.tk.getvar('tk_version')
AttributeError: module '_tkinter' has no attribute 'getvar'
Process finished with exit code 1
The code for the dummy program was:
import tkinter
from tkinter.constants import *
tk = tkinter.Tk()
frame = tkinter.Frame(tk, relief=RIDGE, borderwidth=2)
frame.pack(fill=BOTH,expand=1)
label = tkinter.Label(frame, text="Hello, World")
label.pack(fill=X, expand=1)
button = tkinter.Button(frame, text="Exit", command=tk.destroy)
button.pack(side=BOTTOM)
tk.mainloop()
I tried to uninstall and re-install Tkinter again using both pip and conda. No joy.

why I get an error on Thread-1 when running my python program from an .exe file with a Tkinter GUI?

I design a GUI with Tkinter and also I add a function to convert a .docx file to .PDF file with the docx2pdf library.
I execute the main function of my python code in a Thread because when I run my code from the .exe file the GUI is locked (like it freezes).
I add an event to a button to run the main function in a new thread.
import tkinter
from tkinter import ttk
from threading import *
from docx2pdf import convert
def mProcess():
input = "C:\\test.docx"
output = "C:\\file.pdf"
convert(input,output)
def mainTask():
t = Thread(target=mProcess)
t.daemon = True
t.start()
### GUI
win = Tk()
ttk.Button(win, text = 'Start', command = mainTask).pack(pady=20)
win.mainloop()
If I run this code from my VS code it runs well. The problem only happens when I generate the .exe file of my code and run it.
I generate the exe file with pyinstaller test.py --onefile --windowed.
The error I get when run from the exe file:
Exception in thread Thread-1:
Traceback (most recent call last):
File "win32com\client\dynamic.py", line 89, in _GetGoodDispatch
pywintypes.como_error: (-2147221008, 'CoInitialize has not been called.', None, None)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "threading.py", line 973, in bootstrap_inner
File "threading.py", line 910, in run

(Python tkinter): RuntimeError: main thread is not in main loop

I coded a python GUI program with tkinter that displays a label wherein its text changes every 0.25 seconds, according to the chronology of the list in the variable 'loadings'. I made it work by putting the function as a thread. Otherwise, it would not work. The code works perfectly as intended. However, every time i close the program, a RuntimeError appears and i do not know what the problem is. I searched on the internet for the error but none of what i have found are related to tkinter at all.
code:
from tkinter import *
import threading, time
root = Tk()
loading_label = Label(root)
loading_label.pack()
loadings = ['loading', 'loading.', 'loading..', 'loading...']
def loadingscreen():
while True:
for loading in loadings:
loading_label.config(text=loading)
time.sleep(0.25)
loadingthread = threading.Thread(target=loadingscreen)
loadingthread.start()
root.mainloop()
error:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 932, in _bootstrap_inner
self.run()
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "C:/Users/HP/PycharmProjects/myfirstproject/threadingtest.py", line 14, in loadingscreen
loading_label.config(text=loading)
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1637, in configure
return self._configure('configure', cnf, kw)
File "C:\Users\HP\AppData\Local\Programs\Python\Python38-32\lib\tkinter\__init__.py", line 1627, in _configure
self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
RuntimeError: main thread is not in main loop
Process finished with exit code 0
The reason is that u have used the Threading in the Tkinter loop which I guess we shouldn't.
Safe play is to use after. so Custom label can help us in this case
from tkinter import *
import threading, time
import sys
root = Tk()
class Custom(Label):
def __init__(self,parent,lst):
super().__init__(parent)
self['text']=lst[0]
self.marker=0
self.lst=lst[:]
self.note=len(lst)
self.after(250,self.change)
def change(self):
if self.marker>=self.note:self.marker=0
self['text']=self.lst[self.marker]
self.marker+=1
self.after(250,self.change)
loadings = ['loading', 'loading.', 'loading..', 'loading...']
loading_label = Custom(root,loadings)
loading_label.pack()
# destroy it whenever u want
root.mainloop()

RuntimeError: main thread is not in main loop while using tkinter.simpledialog

Here is my code:
import threading
import tkinter.simpledialog
def showDialog(evt):
dlg = tkinter.simpledialog.SimpleDialog(root,text='Test!', buttons=['OK'])
dlg.go()
def test():
threading.Thread(target=root.event_generate, args=('<<showDialog>>',)).start()
root = tkinter.Tk()
root.bind('<<showDialog>>',showDialog)
tkinter.Button(text = 'showDialog',command = test).pack()
root.mainloop()
I run this code with Python3.4
The First time I click showDialog Button it work perfectly
but if I press OK and click the button again,it raise a RuntimeError:
Exception in thread Thread-2:
Traceback (most recent call last):
File "D:\Program Files\Python34\lib\threading.py", line 921, in _bootstrap_inner
self.run()
File "D:\Program Files\Python34\lib\threading.py", line 869, in run
self._target(*self._args, **self._kwargs)
File "D:\Program Files\Python34\lib\tkinter\__init__.py", line 1501, in event_generate
self.tk.call(args)
RuntimeError: main thread is not in main loop
I'm learning python recently,this code is just a demo.I want to do some work after press the button in sub-thread,because it will cost a few second and I don't want to stuck the UI. When the work is done,it will show a dialog.?
Can someone please tell me how can I do this using tkinter and why this problem occur?
Thanks!And sorry for my poor English.
Mixing threads with GUIs, and in particular tk, is tricky. I do not know all the rules, but unpredictable exceptions and deadlocks are two of the problems. I am a bit surprised that generating an event in a separate thread from the main thread and mainloop worked even once. (Why are you trying that?) A simplified function that run in the same thread does work consistently.
def test():
root.event_generate('<<showDialog>>')

Categories

Resources