skizziks_53

Python tKinter box dragging v1.0

Dec 28th, 2019
237
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.39 KB | None | 0 0
  1. '''
  2. December 23, 2019
  3.  
  4. This is an example ( using Python 3.7 / tKinter on Win10 x64 ) application that allows scrolling a canvas and dragging boxes on a canvas.
  5.  
  6. The canvas visible area is 300 x 300 px, but the scrollable area is 600 x 600 px.
  7.  
  8. This program demonstrates obtaining the final canvas shape object position, and altering it as desired.
  9.    The boxes snap to a grid that is 30px vertically and 100px horizontally.
  10.  
  11.  
  12. '''
  13.  
  14. import tkinter as tk
  15. from tkinter import ttk
  16. from functools import partial
  17.  
  18.  
  19. root = tk.Tk()
  20. root.title( "Scroll/Drag Canvas Example 1.0" )
  21. window_width = 900
  22. window_height = 700
  23. root.minsize(window_width, window_height)
  24. window_position_x = 20
  25. window_position_y = 20
  26. root.geometry('%dx%d+%d+%d' % (window_width, window_height, window_position_x, window_position_y))
  27. root.resizable(True, True)
  28. window_test_color = '#%02x%02x%02x' % (160, 160, 160)
  29. root.config(bg=window_test_color)
  30.  
  31. label_test_color = '#%02x%02x%02x' % (255, 180, 180)
  32.  
  33. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  34. # Below is the scrolling functionality (working)
  35.  
  36. canvas_test_color = '#%02x%02x%02x' % (100, 160, 100)
  37. canvas1 = tk.Canvas(master=root, width=300, height=300, scrollregion=(0,0,600,600), bg=canvas_test_color)
  38. canvas1.place(x=30, y=30)
  39.  
  40. hbar1 = tk.Scrollbar(master=root,orient=tk.HORIZONTAL)
  41. hbar1.place(x=30, y=360, width=200, height=30)
  42.  
  43. vbar1 = tk.Scrollbar(master=root,orient=tk.VERTICAL)
  44. vbar1.place(x=360, y=30, width=30, height=200)
  45.  
  46.  
  47.  
  48. def function_hbar1_movement(event, *args):
  49.     option1 = False
  50.     if option1 == True:
  51.         argList = []
  52.         for x in args:
  53.             argList.append(x)
  54.         print (argList)
  55.     canvas1.xview(event, *args)
  56.  
  57. def function_vbar1_movement(event, *args):
  58.     option2 = False
  59.     if option2 == True:
  60.         argList = []
  61.         for x in args:
  62.             argList.append(x)
  63.         print (argList)
  64.     canvas1.yview(event, *args)
  65.  
  66.  
  67.  
  68. def function_hbar1_set(event, *args):
  69.     option1 = False
  70.     if option1 == True:
  71.         argList = []
  72.         for x in args:
  73.             argList.append(x)
  74.         print (argList)
  75.     hbar1.set(event, *args)
  76.  
  77. def function_vbar1_set(event, *args):
  78.     option2 = False
  79.     if option2 == True:
  80.         argList = []
  81.         for x in args:
  82.             argList.append(x)
  83.         print (argList)
  84.    
  85.     vbar1.set(event, *args)
  86.  
  87.  
  88.  
  89. #hbar1.config(command=canvas1.xview)
  90. #vbar1.config(command=canvas1.yview)
  91. hbar1.config(command=function_hbar1_movement)
  92. vbar1.config(command=function_vbar1_movement)
  93.  
  94. #canvas1.config(xscrollcommand=hbar1.set, yscrollcommand=vbar1.set)
  95. canvas1.config(xscrollcommand=function_hbar1_set, yscrollcommand=function_vbar1_set)
  96.  
  97. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104. def show_canvas_scroll_values(event):
  105.     canvas = event.widget
  106.     x = canvas.canvasx(event.x)
  107.     y = canvas.canvasy(event.y)
  108.     #print canvas.find_closest(x, y)
  109.     canvas_hposition_label.config(text=x)
  110.     canvas_vposition_label.config(text=y)
  111.  
  112. #canvas1.bind('<Configure>', show_canvas_scroll_values)
  113.  
  114.  
  115. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  116. # This section is just four labels to read out the canvas scroll values
  117. # and the last-dragged-box actual xy values, on the 600x600 canvas area.
  118.  
  119. xpos=430
  120. ypos=50
  121. vspacer425 = 30
  122. someLabel = tk.Label(master=root, text="canvas vertical scroll:")
  123. someLabel.place(x=xpos, y=ypos)
  124. xpos=570
  125. canvas_hposition_label = tk.Label(master=root, text="???", bg=label_test_color)
  126. canvas_hposition_label.place(x=xpos, y=ypos)
  127.  
  128. xpos=430
  129. ypos=ypos + vspacer425
  130. someLabel = tk.Label(master=root, text="canvas horizontal scroll:")
  131. someLabel.place(x=xpos, y=ypos)
  132. xpos=570
  133. canvas_vposition_label = tk.Label(master=root, text="???", bg=label_test_color)
  134. canvas_vposition_label.place(x=xpos, y=ypos)
  135.  
  136. xpos=430
  137. ypos=ypos + vspacer425 + vspacer425
  138. someLabel = tk.Label(master=root, text="box xpos:")
  139. someLabel.place(x=xpos, y=ypos)
  140. xpos=530
  141. box_xposition_label = tk.Label(master=root, text="???", bg=label_test_color)
  142. box_xposition_label.place(x=xpos, y=ypos)
  143.  
  144. xpos=430
  145. ypos=ypos + vspacer425
  146. someLabel = tk.Label(master=root, text="box ypos:")
  147. someLabel.place(x=xpos, y=ypos)
  148. xpos=530
  149. box_yposition_label = tk.Label(master=root, text="???", bg=label_test_color)
  150. box_yposition_label.place(x=xpos, y=ypos)
  151.  
  152.  
  153.  
  154. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  155. # this just draws the grid on the canvas.
  156.     # canvas1 scroll region is 600 x 600
  157.  
  158. def draw_test_lines_on_canvas():
  159.     tcolor1 = '#%02x%02x%02x' % (0, 0, 0)
  160.     vspacing = 30
  161.     hspacing = 100
  162.     loopcount = 0
  163.     tValue = vspacing
  164.     while loopcount < 20:
  165.         canvas1.create_line(0, tValue, 600, tValue, fill=tcolor1)
  166.         tValue += vspacing
  167.         loopcount += 1
  168.     loopcount = 0
  169.     tValue = hspacing
  170.     while loopcount < 7:
  171.         canvas1.create_line(tValue, 0, tValue, 600, fill=tcolor1)
  172.         tValue += hspacing
  173.         loopcount += 1
  174.  
  175. draw_test_lines_on_canvas()
  176.  
  177. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  178. # Below is the code for putting the 3 boxes on the canvas, and dragging them.
  179.  
  180. def canvas1_remember(event, *args):
  181.     global canvas1_former_pos
  182.     canvas1_former_pos = event.x, event.y
  183.     #tList = ""
  184.     #for n in args:
  185.     #    tList = tList + str(n) + ", "
  186.     #print ("args = " + tList)
  187.     #x = event.x # <--------------- this is just giving the direct (window) coords of the mouse-down.
  188.     #y = event.y # <--------------- this is just giving the direct (window) coords of the mouse-down.
  189.     #canvas = event.widget
  190.     #x = canvas.canvasx(event.x) #<------------ This is giving the scrolled canvas xy coords of the mouse click.
  191.     #y = canvas.canvasy(event.y) #<------------ This is giving the scrolled canvas xy coords of the mouse click.
  192.     #print ("mouse-down:" + str(canvas.find_closest(x, y))) #<------ this is finding the closest tagged item.
  193.     #print ("mouse-down:" + str(x) + ", " + str(y))
  194.  
  195.  
  196.  
  197. canvas1.bind('<Button>', canvas1_remember)
  198.  
  199.  
  200.  
  201. def on_mouse1_release(box, event):
  202.     global stored_box
  203.     global canvas1_former_pos
  204.     #canvas1.move(stored_box, -10, -10)
  205.     #stored_box.gettags()
  206.     #itemInfo = canvas1.coords(stored_tags[0])
  207.     print ("mouse released from box")
  208.     stored_tags = canvas1.gettags(box)
  209.     sItems = []
  210.     for n in stored_tags:
  211.         sItems.append(n)
  212.     print ( "tag = " + str(sItems[0]))
  213.     #print (stored_box)
  214.  
  215.     # Below is showing the ending drag position.
  216.     itemInfo = canvas1.coords(stored_tags[0]) # <-------- this gets the tag itself
  217.     #print (itemInfo[0]) # = x (string/float format)
  218.     #print (itemInfo[1]) # = y
  219.     #print (itemInfo[2]) # = x + width
  220.     #print (itemInfo[3]) # = y + height
  221.     print (str(itemInfo[0]) + "," + str(itemInfo[1]) + "," + str(itemInfo[2]) + "," + str(itemInfo[3]))
  222.  
  223.     # (Here is where the item's coordinates would be checked for legit settings)
  224.     newxval = check_x_coordinate(str(itemInfo[0]))
  225.     newyval = check_y_coordinate(str(itemInfo[1]))
  226.  
  227.     canvas1.move(sItems[0], newxval, newyval) # <------ this moves the whole item by tag name, the specified coordinates
  228.  
  229.     # Below is showing the ending position after 10,10 move.
  230.     itemInfo = canvas1.coords(stored_tags[0]) # <-------- this gets the tag itself
  231.     #print (itemInfo[0]) # = x (string/float format)
  232.     #print (itemInfo[1]) # = y
  233.     #print (itemInfo[2]) # = x + width
  234.     #print (itemInfo[3]) # = y + height
  235.     print (str(itemInfo[0]) + "," + str(itemInfo[1]) + "," + str(itemInfo[2]) + "," + str(itemInfo[3]))
  236.  
  237.     #new_x = canvas1_former_pos[0] = newxval
  238.     #new_y = canvas1_former_pos[1] = newyval
  239.     new_x = newxval
  240.     new_y = newyval
  241.     canvas1_former_pos = new_x, new_y
  242.  
  243.  
  244. def check_x_coordinate(xValue):
  245.     num_xValue = float(xValue)
  246.     if num_xValue <= 0:
  247.         num_xValue = (num_xValue * -1) # This is checking for a negative x position, and returning it to zero if it exists.
  248.         return num_xValue
  249.     else:
  250.         remainder = num_xValue % 100
  251.         return (remainder * -1)
  252.  
  253.  
  254. def check_y_coordinate(yValue):
  255.     num_yValue = float(yValue)
  256.     if num_yValue <= 0:
  257.         num_yValue = (num_yValue * -1) # This is checking for a negative y position, and returning it to zero if it exists.
  258.         return num_yValue
  259.     else:
  260.         remainder = num_yValue % 30
  261.         return (remainder * -1)
  262.  
  263.  
  264.  
  265.  
  266.  
  267. stored_box = "" # <------- this stores the item ID number, which is just a string of an int value.
  268. stored_tags = [] # <------ this stores the item tag that you assigned, as item[0]
  269.  
  270.  
  271. def ondrag(box, event):
  272.     global stored_box
  273.     global canvas1_former_pos
  274.     #global stored_tags
  275.     stored_box = box
  276.     canvas1.tag_raise(box)
  277.     #print ("box = " + str(box)) # <--------- this is showing the ID number
  278.     #stored_tags = canvas1.gettags(box)
  279.     #sItems = ""
  280.     #for n in stored_tags:
  281.     #    sItems = sItems + n + ", "
  282.     #print ("tag = " + sItems) # <----------- this returns the single tag, and the string "current"
  283.     canvas1.move(box, event.x-canvas1_former_pos[0], event.y-canvas1_former_pos[1]) # This line allows dragging the box in x and y.
  284.     #canvas1.move(box, event.x-canvas1_former_pos[0], 0) # This line only allows dragging the box in the x dimension (left and right along whatever row it is already in).
  285.     canvas1_remember(event)
  286.  
  287.  
  288.  
  289. def add_box(x_pos, y_pos, color, thisTag):
  290.     box = canvas1.create_rectangle(x_pos, y_pos, x_pos+dragBox_width, y_pos+dragBox_height, outline="black", fill=color, tags=(thisTag))
  291.     canvas1.tag_bind(box, '<B1-Motion>', partial(ondrag, box))
  292.     canvas1.tag_bind(box, '<ButtonRelease-1>', partial(on_mouse1_release, box)) # <ButtonRelease-1>
  293.     '''
  294.    https://stackoverflow.com/questions/2679418/how-to-get-the-coordinates-of-an-object-in-a-tkinter-canvas
  295.  
  296.    Note about above: whenever you create an item on a canvas, the canvas returns the item ID number.
  297.    So that just needs to be kept with each shift object, and then you have a way to query all the block positions
  298.    and correct them if they don't fall on the snap-to grid spacing.
  299.    '''
  300.  
  301.  
  302.  
  303. canvas1_former_pos = 0,0
  304. dragBox_width = 80
  305. dragBox_height = 20
  306.  
  307. add_box(80, 100, 'red', 'shiftbox1')
  308. add_box(80, 200, 'green', 'shiftbox2')
  309. add_box(200, 200, 'blue', 'shiftbox3')
  310.  
  311.  
  312. # @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
  313.  
  314.  
  315. root.mainloop()
Advertisement
Add Comment
Please, Sign In to add comment