I wanted to draw regular polygon so I used turtle in tkinter. It works out so I can draw a regular polygon with input data.
However, there are some problems.
1.I want to draw a regular polygon on the canvas in tkinter. However, when you press Run, the turtle graphics window appears and a regular polygon is drawn there.
2.When it finish drawing the regular polygon, the cursor doesn't stop, but it keeps moving.
any help appreciated!!
Exception in Tkinter callback
Traceback (most recent call last):
File "<string>", line 8, in forward
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\turtle.py", line 1638, in forward
self._go(distance)
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\turtle.py", line 1606, in _go
self._goto(ende)
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\turtle.py", line 3182, in _goto
screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\turtle.py", line 544, in _drawline
self.cv.coords(lineitem, *cl)
File "<string>", line 1, in coords
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 2766, in coords
self.tk.call((self._w, 'coords') + args))]
_tkinter.TclError: invalid command name ".!canvas"
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\samsung\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:/Users/samsung/Desktop/정다각형.py", line 19, in buttonclick3
turtle.forward(side)
File "<string>", line 12, in forward
turtle.Terminator
it's the error code in shell.
from tkinter import*
root=Tk()
root.title("도형 그리기")
def buttonclick3():
import turtle
re_po=turtle.RawTurtle(cv)
n=ent_N.get()
n=int(n)
angle=360/n
side=100
while n!=0:
turtle.forward(side)
turtle.left(angle)
n=1
turtle.done()
lb5=Label(root, text="3.정N각형 그리기")
lb6=Label(root, text="N을 입력하세요.")
ent_N=Entry(root, width=70)
bt3=Button(root, text="정다각형 그리기", command=buttonclick3)
cv=Canvas(root, width=700, height=700, bg="white")
lb5.grid(row=8, column=0)
lb6.grid(row=9, column=0, columnspan=3)
ent_N.grid(row=10, column=0, columnspan=3)
bt3.grid(row=11, column=0, columnspan=3)
cv.grid(row=12, column=0, columnspan=3)
root.mainloop()
First you should use re_po instead of turtle on drawing.
Second n=1 should be n -= 1 instead
Final you should not call turtle.done()
def buttonclick3():
import turtle
re_po = turtle.RawTurtle(cv)
n = ent_N.get()
n = int(n)
angle = 360 / n
side = 100
while n != 0:
# use re_po instead of turtle
re_po.forward(side)
re_po.left(angle)
# decrease n by 1
n -= 1
# don't call turtle.done()
Related
I decided to make a tkinter timer but am receiving a very strange error.
Here is the code and the error:
import tkinter as tk
import time
window = tk.Tk()
window.title("Hello wold")
window.geometry("300x300")
timer = int(input("time in seconds"))
for i in range(timer):
timer -= 1
print(timer)
time.sleep(1)
hello = tk.Label("timer")
hello.pack()
tk.mainloop()
The error:
Traceback (most recent call last):
File "main.py", line 14, in <module>
hello = tk.Label("timer")
File "/usr/lib/python3.8/tkinter/__init__.py", line 3143, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "/usr/lib/python3.8/tkinter/__init__.py", line 2561, in __init__
BaseWidget._setup(self, master, cnf)
File "/usr/lib/python3.8/tkinter/__init__.py", line 2530, in _setup
self.tk = master.tk
AttributeError: 'str' object has no attribute 'tk'
To change the text of a label you need to define the text property:
hello = tk.Label(text="timer")
This will set the text of the label to "timer", but if you want to set it as the variable you previously declared (called timer) - simply remove the quotation marks.
hello = tk.Label(text=timer)
This will set the text of the label to whatever the variable 'timer' is equal to.
However you also need to set the window, which leaves the final code to this:
hello = tk.Label(window, text=timer)
I added tk.StringVar in line 16.
I added textvariable=string_variable in line 17
tk.mainloop was relocated outside of the loop block in line 20
Here is code:
import tkinter as tk
import time
window = tk.Tk()
window.title("Hello wold")
window.geometry("300x300")
timer = int(input("time in seconds"))
for i in range(timer):
timer -= 1
print(timer)
time.sleep(1)
string_variable = tk.StringVar(window, timer)
hello = tk.Label(window, textvariable=string_variable)
hello.pack()
tk.mainloop()
Output result:
I want to do something that should be rather simple, but I'm struggling to make it work.
Basically I have 2 Tkinter windows (canvas_tk and control_tk).
In canvas_tk I want to show an image and draw a circle on top of it.
In control_tk I have an Entry to input the radius of the circle to be drawn.
In my code the critical line is at the very bottom of the code:
self.panel = tk.Label(canvas_tk, image=image)
If I make the label in the control_tk or if I dont specify the parent, it actually works fine and draws the circles in the control_tk window
However I want the circles to be drawn in the canvas_tk window
self.panel = tk.Label(image=image) # Works
self.panel = tk.Label(control_tk, image=image) # Works
self.panel = tk.Label(canvas_tk, image=image) # Fails
Here's my minimal code:
import tkinter as tk
from PIL import Image, ImageTk, ImageDraw
control_tk = tk.Tk()
canvas_tk = tk.Tk()
control_tk.geometry("300x300")
canvas_tk.geometry("900x900")
class Drawing:
def __init__(self):
# Numerical entry with a variable traced with callback to "on_change" function
self.radius_var = tk.IntVar()
self.radius_var.trace_variable("w", self.on_change)
tk.Entry(control_tk, textvariable=self.radius_var).grid()
# Initialize image and panel
self.image = Image.new('RGB', (1000, 1000))
self.panel = None
# mainloop for the two tkinter windows
control_tk.mainloop()
canvas_tk.mainloop()
def on_change(self, *args):
print("Value changed") # to check that function is being called
draw = ImageDraw.Draw(self.image)
draw.ellipse((50-self.radius_var.get(), 50-self.radius_var.get(),
50+self.radius_var.get(), 50+self.radius_var.get()),
outline='blue', width=3)
image = ImageTk.PhotoImage(self.image)
if self.panel: # update the image
self.panel.configure(image=image)
self.panel.image = image
else: # if it's the first time initialize the panel
self.panel = tk.Label(canvas_tk, image=image)
self.panel.image = image
self.panel.grid(sticky="w")
Drawing()
And the traceback error basically complains about image not existing
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 508, in get
return self._tk.getint(value)
_tkinter.TclError: expected integer but got ""
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/GIT/142-277-00_pyScuti2/test.py", line 29, in on_change
draw.ellipse((50-self.radius_var.get(), 50-self.radius_var.get(),
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 510, in get
return int(self._tk.getdouble(value))
_tkinter.TclError: expected floating-point number but got ""
Value changed
Value changed
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/GIT/142-277-00_pyScuti2/test.py", line 38, in on_change
self.panel = tk.Label(canvas_tk, image=image)
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2766, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Users\lab\AppData\Local\Programs\Python\Python37\lib\tkinter\__init__.py", line 2299, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage1" doesn't exist
First of all, you should not use multiple Tk() instances. Second, you better not using trace() on tracking input change, use bind('<Return>', ...) to trigger drawing after user enters value and press Enter key. Below is a modified code based on yours:
import tkinter as tk
from PIL import Image, ImageTk, ImageDraw
control_tk = tk.Tk()
control_tk.geometry("300x300+800+600")
canvas_tk = tk.Toplevel() # use Toplevel instead of Tk
canvas_tk.geometry("900x900+10+10")
class Drawing:
def __init__(self):
# Numerical entry with a variable traced with callback to "on_change" function
self.radius_var = tk.IntVar()
entry = tk.Entry(control_tk, textvariable=self.radius_var)
entry.grid()
# binding Enter key on entry to trigger the drawing
entry.bind('<Return>', self.on_change)
# Initialize image and panel
self.image = Image.new('RGB', (1000, 1000))
self.panel = None
# mainloop for the main window
control_tk.mainloop()
def on_change(self, *args):
try:
radius = self.radius_var.get()
except:
print('Invalid number')
return
print("Value changed") # to check that function is being called
draw = ImageDraw.Draw(self.image)
draw.ellipse((50-radius, 50-radius, 50+radius, 50+radius),
outline='blue', width=3)
image = ImageTk.PhotoImage(self.image)
if self.panel:
self.panel.configure(image=image)
else:
self.panel = tk.Label(canvas_tk, image=image)
self.panel.grid(sticky='w')
self.panel.image = image
Drawing()
I'm trying to insert a gif image in a new tkinter window when a button is clicked but I keep getting this error
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\Afro\AppData\Local\Programs\Python\Python35\lib\idlelib\run.py", line 119, in main
seq, request = rpc.request_queue.get(block=True, timeout=0.05)
File "C:\Users\Afro\AppData\Local\Programs\Python\Python35\lib\queue.py", line 172, in get
raise Empty
queue.Empty
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\Afro\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 1549, in __call__
return self.func(*args)
File "C:/Users/Afro/Desktop/mff.py", line 8, in sex
canvas = tkinter.Label(wind,image = photo)
File "C:\Users\Afro\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2605, in __init__
Widget.__init__(self, master, 'label', cnf, kw)
File "C:\Users\Afro\AppData\Local\Programs\Python\Python35\lib\tkinter\__init__.py", line 2138, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: image "pyimage1" doesn't exist
Here's the code. The image and the location actually exists.
import tkinter
def six():
wind = tkinter.Tk()
photo = tkinter.PhotoImage(file = 'American-Crime-Story-1.gif')
self = photo
canvas = tkinter.Label(wind,image = photo)
canvas.grid(row = 0, column = 0)
def base():
ssw = tkinter.Tk()
la = tkinter.Button(ssw,text = 'yes',command=six)
la.grid()
base()
What am I doing wrong?
You are trying to create two instances of Tk window. You can't do that. If you want second window or pop-up window you should use Toplevel() widget.
Also, self doesn't mean anything in this context. Using the widget's image property would be better to keep a reference.
import tkinter
ssw = tkinter.Tk()
def six():
toplvl = tkinter.Toplevel() #created Toplevel widger
photo = tkinter.PhotoImage(file = 'American-Crime-Story-1.gif')
lbl = tkinter.Label(toplvl ,image = photo)
lbl.image = photo #keeping a reference in this line
lbl.grid(row=0, column=0)
def base():
la = tkinter.Button(ssw,text = 'yes',command=six)
la.grid(row=0, column=0) #specifying row and column values is much better
base()
ssw.mainloop()
I'm trying to add a ttk calendar into my Tkinter GUI. The problem is that it raises _tkinter.TclError: can't pack .34164128 inside .34161248.34161448.34161608
import Tkinter
import tkSimpleDialog
import ttkcalendar
class CalendarDialog(tkSimpleDialog.Dialog):
"""Dialog box that displays a calendar and returns the selected date"""
def body(self, master):
self.calendar = ttkcalendar.Calendar(master)
self.calendar.pack()
def apply(self):
self.result = self.calendar.selection
# Demo code:
def main():
root = Tkinter.Tk()
root.wm_title("CalendarDialog Demo")
def onclick():
print 'click'
cd = CalendarDialog(root)
button = Tkinter.Button(root, text="Click me to see a calendar!", command=onclick)
button.pack()
root.update()
root.mainloop()
if __name__ == "__main__":
main()
TRACEBACK:
File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 32, in <module>
main()
File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 23, in main
cd = CalendarDialog(root)
File "C:\Python27\lib\lib-tk\tkSimpleDialog.py", line 64, in __init__
self.initial_focus = self.body(body)
File "C:/Users/Milano/PycharmProjects/MC/plots/ds.py", line 9, in body
self.calendar = ttkcalendar.Calendar(master)
File "C:\Users\Milano\PycharmProjects\MC\plots\ttkcalendar.py", line 52, in __init__
self.__place_widgets() # pack/grid used widgets
File "C:\Users\Milano\PycharmProjects\MC\plots\ttkcalendar.py", line 110, in __place_widgets
self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1940, in pack_configure
+ self._options(cnf, kw))
_tkinter.TclError: can't pack .34164128 inside .34161248.34161448.34161608
Do you know where is the problem?
The fault is that you don't have an __init__ method in the class CalendarDialog. So just rename the body method to __init__. Now you have initialized the instance every time one is made and a pack() method is defined.
I also encountered this problem putting a ttkCalendar into a Dialog box.
I suspect the author of this post "borrowed" the same code for building a calendar as I did:
https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=2ahUKEwiWgYWKsJ3nAhVKl3IEHYrhCU8QFjABegQICBAB&url=https%3A%2F%2Fsvn.python.org%2Fprojects%2Fpython%2Ftrunk%2FDemo%2Ftkinter%2Fttk%2Fttkcalendar.py&usg=AOvVaw0ifTox4EI7CtBFWlRYD_m9
There are two problems I found using this code to create a Calendar object and placing it into a Dialog box.
The first one causes the traceback as shown in the post. The fix is to modify the ttkcalendar.py file to pack the calendar when it is created, not after it is created using the pack() function.
Here is the diff:
102c102
< self._calendar = ttk.Treeview(show='', selectmode='none', height=7)
---
> self._calendar = ttk.Treeview(self, show='', selectmode='none', height=7)
109c109
< self._calendar.pack(in_=self, expand=1, fill='both', side='bottom')
---
> self._calendar.pack(expand=1, fill='both', side='bottom')
Once you make this change, the calendar will appear in the dialog box. However, your problems are not yet done. Another exception occurs when trying to set the minimum size of the calendar:
Exception in Tkinter callback
Traceback (most recent call last):
File "/home/richawil/Applications/anaconda3/envs/TLM/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/home/richawil/Documents/Programming/Apps/TLM/TLM/ttkcalendar.py", line 134, in __minsize
width, height = self._calendar.master.geometry().split('x')
AttributeError: 'Calendar' object has no attribute 'geometry'
I have not been able to fix this issue other than to comment out the call to self.__minsize.
63c62,63
< self._calendar.bind('<Map>', self.__minsize)
---
> # Commented out because _calendar object does not support geometry() function
> #self._calendar.bind('<Map>', self.__minsize)
I am writing a turtle and Tkinter program to display a screen wide canvas to set one dot on which I will then put through a loop, can someone please read my code. Here it is with the error:
import turtle
import Tkinter
root = Tkinter.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
cv = Tkinter.Canvas(root,width=screen_width,height=screen_height)
t = turtle.RawTurtle(cv)
screen = t.getscreen()
frame = Tkinter.Frame(root)
def main():
root.title("Scanner")
cv.pack()
screen.setworldcoordinates(0,0,screen_width,screen_height)
screen.bgcolor("black")
frame.pack()
Tkinter.mainloop()
def setDefaultPos():
t.penup()
t.goto(80,80)
if __name__ == "__main__":
main()
setDefaultPos()
t.dot(1, "white")
Traceback (most recent call last):
File "./demo.py", line 27, in <module>
setDefaultPos()
File "./demo.py", line 21, in setDefaultPos
t.penup()
File "/usr/lib/python2.7/lib-tk/turtle.py", line 2021, in penup
self.pen(pendown=False)
File "/usr/lib/python2.7/lib-tk/turtle.py", line 2337, in pen
self._newLine()
File "/usr/lib/python2.7/lib-tk/turtle.py", line 3123, in _newLine
self.screen._drawline(self.currentLineItem, top=True)
File "/usr/lib/python2.7/lib-tk/turtle.py", line 575, in _drawline
self.cv.tag_raise(lineitem)
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 2314, in tag_raise
self.tk.call((self._w, 'raise') + args)
_tkinter.TclError: invalid command name ".3072604172L"
I also get other errors complaining that "white" is a bad string in respect to t.dot. Please help.
There are two things to fix your code.
First, your drawing happen after mainloop (once you have exited your window), you can fix it my either drawing before the call of root.mainloop, either using a callback to be called during the mainloop.
def callback():
setDefaultPos()
t.dot(1, "white")
#(...)
root.after(1, callback) #call 'callback' function after 1 millisecond
Tkinter.mainloop()
Second, the diameter you ask for (1 pixel) makes your dot not visible...