[Tutor] Tkinter draw line segments
Peter Otten
__peter__ at web.de
Wed Mar 30 11:27:51 EDT 2022
On 30/03/2022 08:35, Phil wrote:
> The segment table contains the start and end points of lines to be drawn
> on the canvas.
>
> seg = {0: (20, 20, 40, 20),
> 1: (44, 24, 44, 44),
> 2: (44, 48, 44, 68),
> 3: (20, 72, 40, 72),
> 4: (16, 48, 16, 68),
> 5: (16, 24, 16, 44),
> 6: (20, 46, 40, 46),
> }
>
> Say I want to draw segments 1 and 2.
>
> num = {1: (seg[1], seg[2])}
>
> The following will draw all of the segments correctly.
>
> for i in range(7):
> self.canvas.create_line(seg[i], width=4, fill="green")
>
> What I haven't sorted out is how to draw segments 1 and 2 without having
> two draw statements. The following does draw the two segments but
> without the break between them.
>
> self.canvas.create_line(num[1], width=4, fill="green")
>
> What I'm trying to come up with is a table entry that tells the draw
> routine how many draw statements there are, one for each segment. No
> doubt I'm making this more complicated than it needs to be.
>
> One way around this is to draw all of the segments in two colours. In
> the above case I would draw segments 1 and 2 green and the remainder
> black. That way I'd only need one draw statement in a for loop with a
> variable fill colour. This would work perfectly on a black background
> but it seems like an amateurish solution.
>
I'd go about it a bit differently. When you draw all segments separately
you can remember them by their ids. To display the desired digits you
can hide/display segments as needed. A complete example:
import tkinter as tk
segments = [
(20, 20, 40, 20),
(44, 24, 44, 44),
(44, 48, 44, 68),
(20, 72, 40, 72),
(16, 48, 16, 68),
(16, 24, 16, 44),
(20, 46, 40, 46),
]
segment_states = [
(1, 1, 1, 1, 1, 1, 0), # 0
(0, 1, 1, 0, 0, 0, 0), # 1
(1, 1, 0, 1, 1, 0, 1), # 2
(1, 1, 1, 1, 0, 0, 1), # 3
(0, 1, 1, 0, 0, 1, 1), # 4
(1, 0, 1, 1, 0, 1, 1), # 5
(0, 0, 1, 1, 1, 1, 1), # 6
(1, 1, 1, 0, 0, 0, 0), # 7
(1, 1, 1, 1, 1, 1, 1), # 8
(1, 1, 1, 0, 0, 1, 1), # 9
]
class Demo:
def __init__(self):
self.root = tk.Tk()
self.label = tk.Label(
self.root,
text="Hit digit key to display corresponding number"
)
self.label.pack()
self.canvas = tk.Canvas(self.root, width=100, height=100)
self.canvas.pack()
self.segment_ids = []
self.draw_segments()
for c in "0123456789":
self.root.bind(
c,
lambda event, n=int(c): self.set_segments(
segment_states[n]
)
)
def draw_segments(self):
for segment in segments:
self.segment_ids.append(
self.canvas.create_line(segment, width=4, fill="green")
)
def set_segments(self, states):
for seg_id, on in zip(self.segment_ids, states):
self.canvas.itemconfigure(
seg_id, state=tk.NORMAL if on else tk.HIDDEN
)
def mainloop(self):
self.root.mainloop()
if __name__ == "__main__":
demo = Demo()
demo.mainloop()
More information about the Tutor
mailing list