Linux 上的 Tkinter Ctrl+Shift+Z
Tkinter Ctrl+Shift+Z on Linux
我想在 Linux (Wayland) 上使用 Tkinter 在 GUI 应用程序中实现自定义重做功能。
这是我当前的代码:
"""Plotting canvas."""
from PIL import Image
from PIL.ImageTk import PhotoImage
from tkinter import NW
from tkinter import Canvas
from tkinter import Event
from tkinter import Tk
from diffusion_scribbles.functions import overlay
from diffusion_scribbles.gui.colors import BLUE, RED
from diffusion_scribbles.selections import DiffusionSelection, Selection
from diffusion_scribbles.types import Color, Dataset, Vector2D
__all__ = ['PlotCanvas']
class PlotCanvas(Canvas):
"""Image canvas."""
def __init__(self, root: Tk, width: int, height: int, **kwargs):
super().__init__(root, width=width, height=height, **kwargs)
self.width = width
self.height = height
self.selection_method: Selection = DiffusionSelection(width, height)
self.bind("<Button-1>", self.start_draw)
self.bind("<B1-Motion>", self.draw)
self.bind("<ButtonRelease-1>", self.stop_draw)
root.bind('<Control-z>', self.undo)
root.bind('<Control-Shift-KeyPress-z>', self.redo)
self._dataset: Dataset | None = None
self._data_points: Image.Image | None = None
self._scribble: Image.Image | None = None
self._image: Image.Image | None = None
self._photo_image: PhotoImage | None = None
self.primary_color: Color = RED
self.secondary_color: Color = BLUE
@property
def dataset(self) -> Dataset | None:
"""Returns the dataset."""
return self._dataset
@dataset.setter
def dataset(self, dataset: Dataset) -> None:
"""Sets the dataset."""
self._dataset = dataset
self._scribble = None
self.image = self._data_points = dataset.draw(
(self.width, self.height)
)
@property
def data_points(self) -> Image.Image:
"""Returns the data points image."""
return self._data_points
@data_points.setter
def data_points(self, data_points: Image.Image) -> None:
"""Sets the data points image."""
self._data_points = data_points
self.image = overlay(data_points, self.scribble)
@property
def scribble(self) -> Image.Image:
"""Returns the scribble image."""
return self._scribble
@scribble.setter
def scribble(self, scribble: Image.Image) -> None:
"""Sets the scribble image."""
self._scribble = scribble
self.image = overlay(self.data_points, scribble)
@property
def image(self) -> Image.Image:
"""Returns the currently displayed image."""
return self._image
@image.setter
def image(self, image: Image.Image) -> None:
"""Sets the currently displayed image."""
self._image = image
self.photo_image = PhotoImage(self._image)
@property
def photo_image(self) -> PhotoImage:
"""Returns the current photo image."""
return self._photo_image
@photo_image.setter
def photo_image(self, photo_image: PhotoImage) -> None:
"""Sets the current photo image."""
self._photo_image = photo_image
self.create_image(0, 0, anchor=NW, image=self._photo_image)
def start_draw(self, event: Event) -> None:
"""Start drawing a line."""
if self.dataset:
self.selection_method.start(
Vector2D(event.x, event.y),
self.primary_color,
self.secondary_color
)
def draw(self, event: Event) -> None:
"""Draw lines."""
if not self.dataset:
return
self.scribble = self.selection_method.move(Vector2D(event.x, event.y))
def stop_draw(self, _: Event) -> None:
"""Stop drawing a line."""
if not self.dataset:
return
self.selection_method.stop()
self.data_points = self.selection_method.colorize(self.dataset)
def undo(self, _: Event) -> None:
"""Undo last action."""
self.scribble = self.selection_method.undo()
self.data_points = self.selection_method.colorize(self.dataset)
def redo(self, _: Event) -> None:
"""Undo last action."""
print('Redo.', flush=True)
虽然撤消工作正常,但当我按下 Ctrl+Shift+Z
的适当组合键时,redo()
永远不会执行。我还尝试了其他变体,例如 '<Control-Shift-z>'
、'<Shift-Control-KeyPress-z>'
和 '<Control-Shift-KeyPress-z>'
无济于事。
如何为 Wayland 下的 Linux 上的自定义重做操作绑定组合键 Ctrl+Shift+Z?
最小可重现示例
from functools import partial
from tkinter import Tk
class Window(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bind('<Control-z>', partial(print, 'Undo'))
self.bind('<Control-Shift-KeyPress-z>', partial(print, 'Redo'))
if __name__ == '__main__':
Window().mainloop()
如果我使用大写 Z
而不是 Shift-z
(小写 z
)
,代码对我有用
import tkinter as tk
def test1(event):
print('test1:', event)
def test2(event):
print('test2:', event)
root = tk.Tk()
root.bind('<Control-z>', test1) # Control+Z
root.bind('<Control-Z>', test2) # Control+Shift+Z
root.mainloop()
如果我使用 '<Control-Shift-Z>'
那么它也可以工作,因为有大写 Z
.
我想在 Linux (Wayland) 上使用 Tkinter 在 GUI 应用程序中实现自定义重做功能。
这是我当前的代码:
"""Plotting canvas."""
from PIL import Image
from PIL.ImageTk import PhotoImage
from tkinter import NW
from tkinter import Canvas
from tkinter import Event
from tkinter import Tk
from diffusion_scribbles.functions import overlay
from diffusion_scribbles.gui.colors import BLUE, RED
from diffusion_scribbles.selections import DiffusionSelection, Selection
from diffusion_scribbles.types import Color, Dataset, Vector2D
__all__ = ['PlotCanvas']
class PlotCanvas(Canvas):
"""Image canvas."""
def __init__(self, root: Tk, width: int, height: int, **kwargs):
super().__init__(root, width=width, height=height, **kwargs)
self.width = width
self.height = height
self.selection_method: Selection = DiffusionSelection(width, height)
self.bind("<Button-1>", self.start_draw)
self.bind("<B1-Motion>", self.draw)
self.bind("<ButtonRelease-1>", self.stop_draw)
root.bind('<Control-z>', self.undo)
root.bind('<Control-Shift-KeyPress-z>', self.redo)
self._dataset: Dataset | None = None
self._data_points: Image.Image | None = None
self._scribble: Image.Image | None = None
self._image: Image.Image | None = None
self._photo_image: PhotoImage | None = None
self.primary_color: Color = RED
self.secondary_color: Color = BLUE
@property
def dataset(self) -> Dataset | None:
"""Returns the dataset."""
return self._dataset
@dataset.setter
def dataset(self, dataset: Dataset) -> None:
"""Sets the dataset."""
self._dataset = dataset
self._scribble = None
self.image = self._data_points = dataset.draw(
(self.width, self.height)
)
@property
def data_points(self) -> Image.Image:
"""Returns the data points image."""
return self._data_points
@data_points.setter
def data_points(self, data_points: Image.Image) -> None:
"""Sets the data points image."""
self._data_points = data_points
self.image = overlay(data_points, self.scribble)
@property
def scribble(self) -> Image.Image:
"""Returns the scribble image."""
return self._scribble
@scribble.setter
def scribble(self, scribble: Image.Image) -> None:
"""Sets the scribble image."""
self._scribble = scribble
self.image = overlay(self.data_points, scribble)
@property
def image(self) -> Image.Image:
"""Returns the currently displayed image."""
return self._image
@image.setter
def image(self, image: Image.Image) -> None:
"""Sets the currently displayed image."""
self._image = image
self.photo_image = PhotoImage(self._image)
@property
def photo_image(self) -> PhotoImage:
"""Returns the current photo image."""
return self._photo_image
@photo_image.setter
def photo_image(self, photo_image: PhotoImage) -> None:
"""Sets the current photo image."""
self._photo_image = photo_image
self.create_image(0, 0, anchor=NW, image=self._photo_image)
def start_draw(self, event: Event) -> None:
"""Start drawing a line."""
if self.dataset:
self.selection_method.start(
Vector2D(event.x, event.y),
self.primary_color,
self.secondary_color
)
def draw(self, event: Event) -> None:
"""Draw lines."""
if not self.dataset:
return
self.scribble = self.selection_method.move(Vector2D(event.x, event.y))
def stop_draw(self, _: Event) -> None:
"""Stop drawing a line."""
if not self.dataset:
return
self.selection_method.stop()
self.data_points = self.selection_method.colorize(self.dataset)
def undo(self, _: Event) -> None:
"""Undo last action."""
self.scribble = self.selection_method.undo()
self.data_points = self.selection_method.colorize(self.dataset)
def redo(self, _: Event) -> None:
"""Undo last action."""
print('Redo.', flush=True)
虽然撤消工作正常,但当我按下 Ctrl+Shift+Z
的适当组合键时,redo()
永远不会执行。我还尝试了其他变体,例如 '<Control-Shift-z>'
、'<Shift-Control-KeyPress-z>'
和 '<Control-Shift-KeyPress-z>'
无济于事。
如何为 Wayland 下的 Linux 上的自定义重做操作绑定组合键 Ctrl+Shift+Z?
最小可重现示例
from functools import partial
from tkinter import Tk
class Window(Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.bind('<Control-z>', partial(print, 'Undo'))
self.bind('<Control-Shift-KeyPress-z>', partial(print, 'Redo'))
if __name__ == '__main__':
Window().mainloop()
如果我使用大写 Z
而不是 Shift-z
(小写 z
)
import tkinter as tk
def test1(event):
print('test1:', event)
def test2(event):
print('test2:', event)
root = tk.Tk()
root.bind('<Control-z>', test1) # Control+Z
root.bind('<Control-Z>', test2) # Control+Shift+Z
root.mainloop()
如果我使用 '<Control-Shift-Z>'
那么它也可以工作,因为有大写 Z
.