【问题标题】:Binding keyboard keys to widgets using events使用事件将键盘键绑定到小部件
【发布时间】:2020-06-08 22:14:52
【问题描述】:

当我尝试绑定按键并启动脚本时,按键会自动按下。 如何使用事件等待按键或提交按钮被按下?

运行时出现此错误:

import tkinter.scrolledtext as scrolledtext
import multiprocessing as mp
from threading import Lock
import subprocess as sub
import tkinter as tk
import threading
import shutil
import signal
import time
import sys
import os
import io


class GUI(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        # self.geometry("860x528")
        self.title("GUI Project")
        self.resizable(0, 0)

        menu = tk.Frame(self, relief="solid")
        container = tk.Frame(self, relief="solid", bg="purple")

        menu.pack(side="left", fill="both", expand=True)
        container.pack(side="right", fill="y", expand=True)

        menu.grid_rowconfigure(0, weight=1)
        container.grid_rowconfigure(0, weight=1)
        container.grid_rowconfigure(1, weight=1)
        container.grid_rowconfigure(2, weight=1)
        container.grid_rowconfigure(3, weight=1)
        container.grid_rowconfigure(4, weight=1)
        container.grid_rowconfigure(5, weight=1)
        container.grid_rowconfigure(6, weight=1)
        container.grid_columnconfigure(0, weight=1)
        container.grid_columnconfigure(1, weight=2)
        container.grid_columnconfigure(2, weight=2)
        container.grid_columnconfigure(3, weight=2)
        container.grid_columnconfigure(4, weight=2)
        container.grid_columnconfigure(5, weight=2)
        container.grid_columnconfigure(6, weight=2)

        self.frames = ["Menu", "CmdCli", "FutureFeature", "FutureFeature2", "FutureFeature3"]

        self.frames[0] = Menu(parent=menu, controller=self)
        self.frames[1] = CmdCli(parent=container, controller=self)
        self.frames[2] = FutureFeature(parent=container, controller=self)
        self.frames[3] = FutureFeature2(parent=container, controller=self)
        self.frames[4] = FutureFeature3(parent=container, controller=self)

        self.frames[0].grid(row=0, column=0, sticky="nsew")
        self.frames[1].grid(row=0, column=0, sticky="nsew")
        self.frames[2].grid(row=0, column=0, sticky="nsew")
        self.frames[3].grid(row=0, column=0, sticky="nsew")
        self.frames[4].grid(row=0, column=0, sticky="nsew")

        self.show_frame(1)

    def show_frame(self, page_name):
        frame = self.frames[page_name]
        print(frame)
        frame.tkraise()
        frame.grid(row=0, column=0, sticky="nsew")


class Menu(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent, bg="black")
        self.controller = controller

        ping_test_button = tk.Button(self, text="CLI CMD", bg="skyblue1", pady=30,
                                     command=lambda: controller.show_frame(1))
        future_feature1_button = tk.Button(self, text="FutureFeature", bg="dark violet", pady=30,
                                           command=lambda: controller.show_frame(2))
        future_feature2_button = tk.Button(self, text="FutureFeature2", bg="pale goldenrod", pady=30,
                                           command=lambda: controller.show_frame(3))
        future_feature3_button = tk.Button(self, text="FutureFeature3", bg="green", pady=30,
                                           command=lambda: controller.show_frame(4))
        app_exit = tk.Button(self, text="Quit", bg="gray40", pady=30,
                             command=lambda: self.terminate())

        ping_test_button.pack(fill="both", expand=True)
        future_feature1_button.pack(fill="both", expand=True)
        future_feature2_button.pack(fill="both", expand=True)
        future_feature3_button.pack(fill="both", expand=True)
        app_exit.pack(fill="both", expand=True)

    @staticmethod
    def terminate():

        while True:
            path = fr'c:/users/{os.getlogin()}/desktop/Gui-Skeleton'

            try:
                shutil.rmtree(path)
                exit()
            except OSError as err:
                print(f"Error Deleting tmp folder! {err}")
                exit()


class CmdCli(tk.Frame):

    file = fr'c:/users/{os.getlogin()}/Desktop/default.txt'
    newfile = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/default-tmp.txt'
    lastfile = fr'c:/users/{os.getlogin()}/Desktop/logger.txt'

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent, bg="skyblue1")
        self.controller = controller

        self.command_label = tk.Label(self, text="Enter Command : ", padx=7, pady=5, bg="skyblue1")
        self.command_input_box = tk.Entry(self)
        self.command_input_box.bind(signal., self.thread_handler(self.command_input_box.get()))

        self.submit_button = tk.Button(self, text="Submit", width=10, height=1,
                                       command=lambda: self.thread_handler(self.command_input_box.get()))
        self.clear_field_button = tk.Button(self, text="Clear Field", width=10, padx=2,
                                            command=lambda: self.clear_boxes(self.command_input_box))
        self.clear_file_button = tk.Button(self, text="Clear File", width=10,
                                           command=lambda:
                                           open(self.lastfile, 'w+').close())
        self.clear_window_button = tk.Button(self, text="Clear Window", width=10,
                                             command=lambda: self.clean_window())
        self.stop_button = tk.Button(self, text="Stop", padx=20, command=lambda: self.stop_process())

        self.grid_columnconfigure(0, minsize=20, weight=0)
        self.grid_columnconfigure(1, minsize=20, weight=2)
        self.grid_columnconfigure(2, minsize=5, weight=3)
        self.grid_columnconfigure(3, minsize=20, weight=2)
        self.grid_rowconfigure(0, minsize=50, weight=0)
        self.grid_rowconfigure(1, minsize=20, weight=0)
        self.grid_rowconfigure(2, minsize=30, weight=0)
        self.grid_rowconfigure(3, minsize=10, weight=0)
        self.grid_rowconfigure(4, minsize=10, weight=0)
        self.grid_rowconfigure(5, minsize=10, weight=0)

        self.command_label.grid(row=0, column=1, sticky="nsew")
        self.command_input_box.grid(row=1, column=1, sticky="nsew")
        self.clear_window_button.grid(row=3, column=1, sticky="w")
        self.clear_file_button.grid(row=3, column=1, sticky="n")
        self.clear_field_button.grid(row=1, column=1, sticky="e")
        self.submit_button.grid(row=3, column=1, sticky="se")
        self.stop_button.place(x=510, y=106)

        self.text_widget()

    def clear_files(self):
        open(self.file, 'w+').close()

    def text_widget(self):

        self.text_window = tk.scrolledtext.ScrolledText(self, bg="slategray1")
        self.text_window.insert(tk.END, "")
        self.text_window.config(state=tk.NORMAL)
        self.text_window.grid(row=5, column=1, rowspan=3, sticky="nsew")

.................................................. ..................................................... ..................................................... ..................................................... ..................................................... ....................

【问题讨论】:

  • 请不要发布代码或堆栈跟踪的图片。
  • 这样更好吗?
  • 你试过使用 lambda 吗?像这样:self.url_input_box.bind("<Return>", lambda: self.thread_handler(self.url_input_box.get()))?
  • 是的,我得到一个错误:TypeError: () 接受 0 个位置参数,但给出了 1 个
  • bind 的回调需要一个参数,即事件对象。所以应该是self.url_input_box.bind("<Return>", lambda e: ...)

标签: python user-interface tkinter key-bindings


【解决方案1】:

通过将等待表达式的 'lambda' 更改为 'lambda e:'。

class CmdCli(tk.Frame):

    file = fr'c:/users/{os.getlogin()}/Desktop/default.txt'
    newfile = fr'c:/users/{os.getlogin()}/Desktop/Gui-Skeleton/default-tmp.txt'
    lastfile = fr'c:/users/{os.getlogin()}/Desktop/logger.txt'

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent, bg="skyblue1")
        self.controller = controller

        self.command_label = tk.Label(self, text="Enter Command : ", padx=7, pady=5, bg="skyblue1")
        self.command_input_box = tk.Entry(self)
        self.command_input_box.bind('<Return>', lambda e: self.thread_handler(self.command_input_box.get()))

        self.submit_button = tk.Button(self, text="Submit", width=10, height=1,
                                       command=lambda: self.thread_handler(self.command_input_box.get()))
        self.clear_field_button = tk.Button(self, text="Clear Field", width=10, padx=2,
                                            command=lambda: self.clear_boxes(self.command_input_box))
        self.clear_file_button = tk.Button(self, text="Clear File", width=10,
                                           command=lambda:
                                           open(self.lastfile, 'w+').close())
        self.clear_window_button = tk.Button(self, text="Clear Window", width=10,
                                             command=lambda: self.clean_window())
        self.stop_button = tk.Button(self, text="Stop", padx=20, command=lambda: self.stop_process())

        self.grid_columnconfigure(0, minsize=20, weight=0)
        self.grid_columnconfigure(1, minsize=20, weight=2)
        self.grid_columnconfigure(2, minsize=5, weight=3)
        self.grid_columnconfigure(3, minsize=20, weight=2)
        self.grid_rowconfigure(0, minsize=50, weight=0)
        self.grid_rowconfigure(1, minsize=20, weight=0)
        self.grid_rowconfigure(2, minsize=30, weight=0)
        self.grid_rowconfigure(3, minsize=10, weight=0)
        self.grid_rowconfigure(4, minsize=10, weight=0)
        self.grid_rowconfigure(5, minsize=10, weight=0)

        self.command_label.grid(row=0, column=1, sticky="nsew")
        self.command_input_box.grid(row=1, column=1, sticky="nsew")
        self.clear_window_button.grid(row=3, column=1, sticky="w")
        self.clear_file_button.grid(row=3, column=1, sticky="n")
        self.clear_field_button.grid(row=1, column=1, sticky="e")
        self.submit_button.grid(row=3, column=1, sticky="se")
        self.stop_button.place(x=510, y=106)

再次感谢 acw1668!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    • 2014-03-28
    相关资源
    最近更新 更多