Python делает фиксированную рамку, в то время как большой холст внутри - PullRequest
0 голосов
/ 04 ноября 2019

ширина или \ и высота = размер

У меня есть frame 300x300 и canvas 600x600 (холст внутри рамки).

Я хочу фиксированный размер frame, потому чтоесли я изменю canvas размер -> мой размер кадра станет равным ширине и высоте холста! Как сделать фиксированный размер frame, чтобы мои canvas не отображались?

from tkinter import *

class MainWindow():
  def __init__(self):
    self.canvas_width = 600   # more than frame width
    self.canvas_height = 600  # more than frame height

    self.frame = Frame(root, width=300, height=300) # should be fixed in the window
    self.frame.grid(row=0, column=0)
    self.canvas = Canvas(self.frame, bg='bisque', width=self.canvas_width, height=self.canvas_height,
                         scrollregion=(0, 0, self.canvas_width, self.canvas_height))
    self.frame.propagate(False)

    self.hbar = Scrollbar(self.frame, orient=HORIZONTAL)
    self.hbar.pack(side=BOTTOM, fill=X)
    self.hbar.config(command=self.canvas.xview)

    self.vbar = Scrollbar(self.frame, orient=VERTICAL)
    self.vbar.pack(side=RIGHT, fill=Y)
    self.vbar.config(command=self.canvas.yview)

    # self.canvas.config(width=300, height=300)
    self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)
    self.canvas.pack(side=LEFT, expand=True, fill=BOTH)

    self.canvas.bind("<ButtonPress-1>", self.scroll_start)
    self.canvas.bind("<B1-Motion>", self.scroll_move)

    self.grid(self.canvas)

  def grid(self, canvas):
    for line in range(0, self.canvas_height, 10):
        canvas.create_line([(line, 0), (line, self.canvas_height)], fill='#d9d9d9')
    for line in range(0, self.canvas_width, 10):
        canvas.create_line([(0, line), (self.canvas_width, line)], fill='#d9d9d9')

  def scroll_start(self, event):
    self.canvas.scan_mark(event.x, event.y)

  def scroll_move(self, event):
    self.canvas.scan_dragto(event.x, event.y, gain=1)

if __name__ == '__main__':
  root = Tk()
  root.geometry('850x700')
  MainWindow()
  root.mainloop()

image

1 Ответ

0 голосов
/ 04 ноября 2019

Похоже, вы неправильно понимаете, как работают холсты. Вам не нужно создавать большой холст. Физический размер содержит гораздо больший виртуальный холст. Фактически, определенно не хочет, чтобы больший холст был частично скрыт за меньшим кадром, потому что часть холста была бы скрыта за кадром.

Другими словами, если у вас естьхолст размером 300x300 на экране, вы все равно можете рисовать на нем, как если бы он был 600x600 или 6000x6000 или 60000x60000.

Вы делаете это, настраивая scrollregion холста, который сообщает холсту, сколько места вы планируете рисовать. Например, чтобы иметь холст 300x300, но рисовать так, как если бы он был 600x600,вы бы настроили его так:

canvas.configure(scrollregion=(0,0,599,599))

Вот простой пример, показывающий, как это работает. Обратите внимание, что мы размещаем объекты по углам, и можно прокрутить все четыре угла.

import tkinter as tk

root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=300, background="black")
ysb = tk.Scrollbar(root, command=canvas.yview, orient="vertical")
xsb = tk.Scrollbar(root, command=canvas.xview, orient="horizontal")
canvas.configure(yscrollcommand=ysb.set, xscrollcommand=xsb.set)

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

canvas.grid(row=0, column=0, sticky="nsew")
ysb.grid(row=0, column=1, sticky="ns")
xsb.grid(row=1, column=0, sticky="ew")

# designate that we want to draw in a 600x600 virtual canvas
canvas.configure(scrollregion=(0,0,599,599))

canvas.create_line(0,0,599,599, width=1, fill="white")
canvas.create_line(0,599, 599, 0, width=1, fill="white")
canvas.create_rectangle(0,0,19,19, fill="red")
canvas.create_rectangle(579, 579, 599,599, fill="red")
canvas.create_rectangle(579, 0, 599, 19, fill="red")
canvas.create_rectangle(0, 579, 19, 599, fill="red")
canvas.create_rectangle(290,290, 310, 310, fill="green")

root.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...