Python Forum
The coordinates of the Entry widget (canvas) when moving
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
The coordinates of the Entry widget (canvas) when moving
#1
sorry i don't know english well
Did scrolling objects on canvas through the canvas.move () method - changing the coordinates of the object when scrolling the mouse wheel (canvas2.bind_all ("MouseWheel", fun_mooving)). Everything turned out fine, all objects (canvas.create_text, canvas.create_image) move as they should. But the problem surfaced when I add a few objects of type Entry (canvas) to the canvas. If you smoothly turn the mouse wheel, then there is a noticeable slight delay when moving Entry objects, while other objects (texts, pictures) move without problems, as they should. If the mouse wheel is twisted sharply, then the coordinates when moving the Entry can be completely lost - do not get up to the coordinates put by it. What could be the problem?

import tkinter as tk
from tkinter import*

global v_entry

root = tk.Tk()
root.geometry('600x800+10+10')
root.resizable(width=False, height=False)

def xxx():
    global v_entry, list_v
    txt1 = 'txt1txt1txt1txt1txt1txt1txt1'
    v_01 = canvas2.create_text(30, 10, text=txt1, anchor=NW)
    v_entry[0] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[0]).insert(0, '000')
    (v_entry[0]).place(x=100, y=25)
    
    txt1 = 'txt2txt2txt2txt2txt2txt2txt2'
    v_02 = canvas2.create_text(30, 50, text=txt1, anchor=NW)
    v_entry[1] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[1]).insert(0, '101')
    (v_entry[1]).place(x=100, y=75)
    
    txt1 = 'txt3txt3txt3txt3txt3txt3txt3'
    v_03 = canvas2.create_text(30, 100, text=txt1, anchor=NW)
    v_entry[2] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[2]).insert(0, '202')
    (v_entry[2]).place(x=100, y=125)
    
    txt1 = 'txt4txt4txt4txt4txt4txt4txt4'
    v_04 = canvas2.create_text(30, 150, text=txt1, anchor=NW)
    v_entry[3] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[3]).insert(0, '303')
    (v_entry[3]).place(x=100, y=175)
    
    txt1 = 'txt5txt5txt5txt5txt5txt5txt5'
    v_05 = canvas2.create_text(30, 200, text=txt1, anchor=NW)
    v_entry[4] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[4]).insert(0, '404')
    (v_entry[4]).place(x=100, y=225)
    
    txt1 = 'tx6txt6txt6txt6txt6txt6txt6'
    v_06 = canvas2.create_text(30, 250, text=txt1, anchor=NW)
    v_entry[5] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[5]).insert(0, '505')
    (v_entry[5]).place(x=100, y=275)
    
    txt1 = 'tx7txt7tx7txt7txt7txt7txt7'
    v_07 = canvas2.create_text(30, 300, text=txt1, anchor=NW)
    v_entry[6] =Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    (v_entry[6]).insert(0, '606')
    (v_entry[6]).place(x=100, y=325)
    
    txt1 = 'tx8txt8txt8txt8txt8txt8txt8'
    v_08 = canvas2.create_text(30, 350, text=txt1, anchor=NW)
    
    
    list_v = [v_01, v_02, v_03, v_04, v_05, v_06, v_07, v_08]

def fun_mooving(event):
    global v_entry, list_v
    
    y=int(event.delta/2)
    
    for i1 in list_v:
        canvas2.move(i1, 0, y)
        
        
    for i in v_entry:        
        y1 = i.winfo_y()
        y1 += y        
        i.place(x = 100, y = y1)
        

canvas1 = Canvas(root, width=600, height=800, highlightthickness=0)
canvas1.place(x=0, y=0)

canvas2 = Canvas(canvas1, width=600, height=750, highlightthickness=0)
canvas2.place(x=0, y=50)

v_entry = []
for i in range (7): 
    v_entry.append(Entry(canvas2, bd = 0, justify = CENTER, width = 6))

xxx()
canvas2.bind_all("<MouseWheel>", fun_mooving)
root.mainloop()
Reply
#2
Are you opposed to using a scrollbar? bind your mouse wheel to the scrollbar?
scrolled canvas
search for scrolled canvas, tkinter scrollbar, I have only used tk.canvas.move for moving canvas items oval rectangles etc.( it has it limits with those object) Not widgets like buttons and entries
here's a link to scrolling widgets:
group of widgets
Reply
#3
Thanks for the answer, but maybe I still do not know python well, but these methods do not suit me. I make a game and transparency of all objects is very important to me. I can’t do widgets, because they do not have transparency, but I simply can’t insert text and a picture into the frame, so I have to invent “crutches”.
I would just like to know - why the coordinates do not work out the way they should be?
Reply
#4
Hi berckut72
Here something to experiment with. Try to forget globals:
import tkinter as tk
 
root = tk.Tk()
root.geometry('600x800+10+10')
root.resizable(width=False, height=False)

def build_canvas_setup(canvas):
    xorg_txt = 30
    yorg_txt = 10
    xorg_entry = 100
    yorg_entry = 40
    ystep = 50
    
    entry_vars = list()
    
    for index in range(8):
        # Place text canvas object
        tx_slice = 'txt{}'.format(index+1)
        txtn = tx_slice*7
        canvas.create_text(xorg_txt, yorg_txt+ystep*index, text=txtn,
            anchor=tk.NW, tags='all')
            
        # Place entry widget as canvas object
        entry_var = tk.StringVar()
        entry = tk.Entry(canvas, bd = 0, justify = tk.CENTER, bg = '#7F7F7F',
            fg='white', textvariable=entry_var, width = 6)
        canvas.create_window(
            xorg_entry, yorg_entry+ystep*index, window=entry, tags='all')
        entry_vars.append(entry_var)
    
    return entry_vars    
 
def button4_event(event):
    # Linux wheel event
    print('Button-4')
    move_canvas_objects('up')
    
def button5_event(event):
    # Linux wheel event
    print('Button-5')
    move_canvas_objects('down')

def mouse_wheel_events(event):
    # Window wheel events
    if event.delta == -120:
        direction = 'down'
    elif event.delta == 120:
        direction = 'up'
    else:
        return
    move_canvas_objects(direction)
        
def move_canvas_objects(direction):
    if direction == 'up':
        canvas1.move('all', 0, -1)
    elif direction == 'down':
        canvas1.move('all', 0, 1)
    
canvas1 = tk.Canvas(root, width=600, height=750, highlightthickness=0)
canvas1.pack()
 
entry_vars = build_canvas_setup(canvas1)

for index, entry_var in enumerate(entry_vars):
    entry_value = 100 + index
    entry_var.set(entry_value)
    
# For Linux only    
canvas1.bind('<Button-4>', button4_event)
canvas1.bind('<Button-5>', button5_event)
# For Windows only
canvas1.bind('<MouseWheel>', mouse_wheel_events)

root.mainloop()
Greetings from wuf :-)
Reply
#5
Hi WUF!
I really liked your decision! Well done!
I did differently. I solved this problem, but in a slightly different way - I linked Entry coordinates to canvas.create_text coordinates. Everything works fine too.
But why there is a coordinate skipping for Entry - I still do not understand.
Reply
#6
Hi berckut72

If you whant to move a entry widget on a canvas like an other canvas object as text, images or geometric figures you must enbed the entry widget in a canvas object called window. To move the entry object together with other canvas objects you must use the coordinates of the window object not the place method of the entry widget.

wuf :-)

Here your modified script to try out:

import tkinter as tk
from tkinter import*
 
global v_entry
 
root = tk.Tk()
root.geometry('600x800+10+10')
root.resizable(width=False, height=False)
 
def xxx():
    global v_entry, list_v, list_win
    
    txt1 = 'txt1txt1txt1txt1txt1txt1txt1'
    v_01 = canvas2.create_text(30, 0, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '000')
    #(v_entry[0]).place(x=100, y=25)
    win_01 = canvas2.create_window(100, 25, window=entry)
     
    txt1 = 'txt2txt2txt2txt2txt2txt2txt2'
    v_02 = canvas2.create_text(30, 50, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '101')
    v_entry.append(entry)
    #(v_entry[1]).place(x=100, y=75)
    win_02 = canvas2.create_window(100, 75, window=entry)
     
    txt1 = 'txt3txt3txt3txt3txt3txt3txt3'
    v_03 = canvas2.create_text(30, 100, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '202')
    v_entry.append(entry)
    #(v_entry[2]).place(x=100, y=125)
    win_03 = canvas2.create_window(100, 125, window=entry)
         
    txt1 = 'txt4txt4txt4txt4txt4txt4txt4'
    v_04 = canvas2.create_text(30, 150, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '303')
    v_entry.append(entry)
    #(v_entry[3]).place(x=100, y=175)
    win_04 = canvas2.create_window(100, 175, window=entry) 
     
    txt1 = 'txt5txt5txt5txt5txt5txt5txt5'
    v_05 = canvas2.create_text(30, 200, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '404')
    v_entry.append(entry)
    #(v_entry[4]).place(x=100, y=225)
    win_05 = canvas2.create_window(100, 225, window=entry) 
     
    txt1 = 'tx6txt6txt6txt6txt6txt6txt6'
    v_06 = canvas2.create_text(30, 250, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '505')
    v_entry.append(entry)
    #(v_entry[5]).place(x=100, y=275)
    win_06 = canvas2.create_window(100, 275, window=entry) 
     
    txt1 = 'tx7txt7tx7txt7txt7txt7txt7'
    v_07 = canvas2.create_text(30, 300, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '606')
    #(v_entry[6]).place(x=100, y=325)
    win_07 = canvas2.create_window(100, 325, window=entry) 
     
    txt1 = 'tx8txt8txt8txt8txt8txt8txt8'
    v_08 = canvas2.create_text(30, 350, text=txt1, anchor=NW)
    entry = Entry(canvas2, bd = 0, justify = CENTER, bg = '#7F7F7F', width = 6)
    entry.insert(0, '707')
    v_entry.append(entry)
    #(v_entry[6]).place(x=100, y=325)
    win_08 = canvas2.create_window(100, 375, window=entry) 
     
     
    list_v = [v_01, v_02, v_03, v_04, v_05, v_06, v_07, v_08]
    list_win = [win_01, win_02, win_03, win_04, win_05, win_06, win_07, win_08]
 
def fun_mooving(event):
    global v_entry, list_v, list_win
     
    y=int(event.delta/2)
     
    for i1 in list_v:
        canvas2.move(i1, 0, y)
         
         
    #for i in v_entry:        
        #y1 = i.winfo_y()
        #y1 += y        
        #i.place(x = 100, y = y1)
         
    for win in list_win:
        canvas2.move(win, 0, y)
 
canvas1 = Canvas(root, width=600, height=800, highlightthickness=0)
canvas1.place(x=0, y=0)
 
canvas2 = Canvas(canvas1, width=600, height=750, highlightthickness=0)
canvas2.place(x=0, y=50)
 
v_entry = []
#for i in range (7): 
    #v_entry.append(Entry(canvas2, bd = 0, justify = CENTER, width = 6))
 
xxx()
canvas2.bind_all("<MouseWheel>", fun_mooving)
root.mainloop()
wuf :-)
Reply
#7
Thanks! I could not understand how to use create_window, although I guessed that I needed to use it. Now I figured out how to use create_window.
The tkinter widget and the canvas object have geometry (height, width, x position, y position) and it would be nice if they had the same methods. But - that is, then we use)))

I really liked Python and after a short time studying it I wanted to make an RTS space game, probably, like many others, they also start with games))). With python classes, I only recently understood how to work, and in the game I already wrote more than 6,000 lines of code. I don’t want to rewrite everything, I’ll leave this game without classes.

I speak English poorly, my native language is Russian.
Reply
#8
Ok berckut72
So far I understood what you wrote in English. English is also not my main language. Thanks to google translator, I hope that my english is understood to some extent :-)

As you can see in my last post, I placed the entry widgets in canvas window objects. In your first post you mentioned that there is a delay when moving the objects with the mouse wheel on the canvas between the text objects and the entry widget. Is this still the case with the modified script in my last script?

Ok berckut72
I wish you the best of luck programming your game. I recommend using more classes when programming. Try to get away from global variables. Mainly only use constants at the global level.

wuf :-)
Reply
#9
Now objects are moving correctly.
I did like this:
y1 = canvas2.bbox(canvas_text[0])[1]#y coordinate after moving the text object

x1 = v_entry[0].winfo_x() #x coordinate

v_entry[0].place_forget()

v_entry[0].place(x = x1, y = y1) #moving Entry vertically

Your code checked and it works well too!
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  ValueError: could not convert string to float: '' fron Entry Widget russellm44 5 500 Mar-06-2024, 08:42 PM
Last Post: russellm44
  [Tkinter] entry widget DPaul 5 1,439 Jul-28-2023, 02:31 PM
Last Post: deanhystad
  Tkinter Exit Code based on Entry Widget Nu2Python 6 2,879 Oct-21-2021, 03:01 PM
Last Post: Nu2Python
  [Tkinter] canvas widget scroll issue chrisdb 2 3,783 Apr-07-2021, 05:48 AM
Last Post: chrisdb
  method to add entries in multi columns entry frames in self widget sudeshna24 2 2,215 Feb-19-2021, 05:24 PM
Last Post: BashBedlam
  Entry Widget issue PA3040 16 6,659 Jan-20-2021, 02:21 PM
Last Post: pitterbrayn
  [Tkinter] password with Entry widget TAREKYANGUI 9 5,778 Sep-24-2020, 05:27 PM
Last Post: TAREKYANGUI
  [Tkinter] Get the last entry in my text widget Pedroski55 3 6,295 Jul-13-2020, 10:34 PM
Last Post: Pedroski55
  How to place global tk text widget in class or on canvas puje 1 2,284 Jul-04-2020, 09:25 AM
Last Post: deanhystad
  How to retreive the grid location of an Entry widget kenwatts275 7 4,481 Apr-24-2020, 11:39 PM
Last Post: Larz60+

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020