首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何为键绑定python tkinter设置多个类实例的焦点

如何为键绑定python tkinter设置多个类实例的焦点
EN

Stack Overflow用户
提问于 2022-07-22 02:43:46
回答 1查看 97关注 0票数 0

对于绑定,我在python焦点方面做错了什么?

我试图将按钮小部件绑定到键盘enter,但是没有发生任何事情,或者焦点结束在要加载的类的最后一个实例上。

我在self.bind('<Return>', lambda e: self.convert)之后将button.nothing添加到基本代码中。试过container.bind('<Return>', lambda e: self.convert)什么都没做。我不明白为什么代码没有绑定除了焦点之外的关键事件在错误的位置(焦点总是在类的最后一个实例上)。这是我在https://github.com/photodude/Tkconverter工作的代码

在修改代码成为更多OOP之前,在自述文件中链接到源非OOP教程和所有文件到源教程。

如何将焦点放在类的"active“用户可见实例上?

上面提供了一个指向代码的链接,这是一个最小的、可重复的例子。

  1. 运行App.py文件
  2. 在GUI中选择"F到C“
  3. ,在输入框中输入一个数值(如98或100),然后按enter键.

< code >G 212

当您打开"F到C“并按enter键时,您会得到一个弹出错误”无法将字符串转换为浮动“,但是当您使用"C到F”时,就会发生正确的操作(温度转换)。在"F到C“上弹出的”错误“与单击”转换“按钮时相同,而输入字段为空白或有数值以外的其他内容。这个弹出错误发生在"C到F“上,然后按enter键,输入一个空白条目或非数字值。如果您在"F到C“或"C到F”上,请在输入框中输入一个数字值(如98或100),然后单击“转换”按钮,一切都按预期工作。

预期的绑定行为是指对用户可见的活动实例具有键绑定的活动焦点,如“转换”按钮所具有的。

按社区要求张贴的代码。有关当前代码和尝试修复的历史记录,请参见Github。App.py

代码语言:javascript
运行
复制
# source https://www.pythontutorial.net/tkinter/tkraise/

import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showerror
from ControlFrame import ControlFrame

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title('Temperature Converter')
        self.geometry('300x120')
        self.resizable(False, False)


if __name__ == "__main__":
    app = App()
    ControlFrame(app)
    app.mainloop()

ControFrame.py

代码语言:javascript
运行
复制
# source https://www.pythontutorial.net/tkinter/tkraise/
import tkinter as tk
from tkinter import ttk
from ConverterFrame import ConverterFrame
from TemperatureConverter import TemperatureConverter

class ControlFrame(ttk.LabelFrame):
    def __init__(self, container):

        super().__init__(container)
        self['text'] = 'Options'

        # radio buttons
        self.selected_value = tk.IntVar()

        ttk.Radiobutton(
            self,
            text='F to C',
            value=0,
            variable=self.selected_value,
            command=self.change_frame).grid(column=0, row=0, padx=5, pady=5)

        ttk.Radiobutton(
            self,
            text='C to F',
            value=1,
            variable=self.selected_value,
            command=self.change_frame).grid(column=1, row=0, padx=5, pady=5)

        self.grid(column=0, row=1, padx=5, pady=5, sticky='ew')

        # initialize frames
        self.frames = {}
        self.frames[0] = ConverterFrame(
            container,
            'Fahrenheit',
            TemperatureConverter.fahrenheit_to_celsius
            )
        self.frames[1] = ConverterFrame(
            container,
            'Celsius',
            TemperatureConverter.celsius_to_fahrenheit
            )

        self.change_frame()

    def change_frame(self):
        for frame in self.frames.values():
            frame.reset()
            frame.grid_remove()
        frame = self.frames[self.selected_value.get()]
        frame.reset()
        frame.tkraise()
        frame.grid()
        frame.focus_set()

ConverterFrame.py

代码语言:javascript
运行
复制
# source https://www.pythontutorial.net/tkinter/tkraise/
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showerror

class ConverterFrame(ttk.Frame):
    def __init__(self, container, unit_from, converter):
        super().__init__(container)

        self.unit_from = unit_from
        self.converter = converter

        self.master.bind('<Return>', lambda event=None: self.enter_key())

        # field options
        options = {'padx': 5, 'pady': 0}

        # temperature label
        self.temperature_label = ttk.Label(self, text=self.unit_from)
        self.temperature_label.grid(column=0, row=0, sticky='w', **options)

        # temperature entry
        self.temperature = tk.StringVar()
        self.temperature_entry = ttk.Entry(self, textvariable=self.temperature)
        self.temperature_entry.grid(column=1, row=0, sticky='w', **options)
        self.temperature_entry.focus()

        # button
        self.convert_button = ttk.Button(self, text='Convert')
        self.convert_button.grid(column=2, row=0, sticky='w', **options)
        self.convert_button.configure(command=self.convert)
        # self.convert_button.bind('<Return>', lambda event=None: self.convert)

        # result label
        self.result_label = ttk.Label(self)
        self.result_label.grid(row=1, columnspan=3, **options)

        # add padding to the frame and show it
        self.grid(column=0, row=0, padx=5, pady=5, sticky="nsew")

    def convert(self, event=None):
        """  Handle button click event
        """
        try:
            input_value = float(self.temperature.get())
            result = self.converter(input_value)
            self.result_label.config(text=result)
        except ValueError as error:
            showerror(title='Error', message=error)

    def reset(self):
        self.temperature_entry.delete(0, "end")
        self.result_label.text = ''

    def enter_key(self):
        self.convert()

TemperatureConverter.py

代码语言:javascript
运行
复制
# source https://www.pythontutorial.net/tkinter/tkraise/
class TemperatureConverter:
    @staticmethod
    def fahrenheit_to_celsius(f, format=True):
        result = (f - 32) * 5/9
        if format:
            return f'{f} Fahrenheit = {result:.2f} Celsius'
        return result

    @staticmethod
    def celsius_to_fahrenheit(c, format=True):
        result = c * 9/5 + 32
        if format:
            return f'{c} Celsius = {result:.2f} Fahrenheit'
        return result

尝试了来自Python Tkinter: Binding Keypress Event to Active Tab in ttk.Notebook的解决方案,如下所示,但没有成功

代码语言:javascript
运行
复制
class ConverterFrame(ttk.Frame):
    def __init__(...):
        ...
        tag = str(self)
        self._add_bindtag(self, tag)
        self.bind_class(tag, '<Return>', lambda event=None: self.convert())

    def _add_bindtag(self, widget, tag):
        bindtags = widget.bindtags()
        if tag not in bindtags:
            widget.bindtags((tag,) + bindtags)
        for child in widget.winfo_children():
            self._add_bindtag(child, tag)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-16 03:37:16

这里的解决方案是更正ControlFrame.py,以初始化change_frame()上每个框架的实例。源教程中的原始错误实例化了ConverterFrame()类,最后一个类将替换以前所有与焦点和绑定相关的错误。

移动self.frames[0] = ConverterFrame(...)..。转换成特定的函数并调用change_frame()上的函数,纠正了帧替换问题。

完全修改的代码在GitHub https://github.com/photodude/Tkconverter

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73074571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档