0

我的一个 python 脚本中有这个函数,它会抛出一个 Tkinter 简单对话框屏幕来要求一些简单的用户输入。该功能有效。但是,它有两个问题

  1. 它打开了两个窗口,而我只需要一个。但是,如果我删除master = Tk()我会收到错误消息:

AttributeError:“NoneType”对象没有属性“winfo_viewable”

在某一点上找出一个会很好,但我的主要问题是第二个:

  1. 每当出现简单的对话屏幕时,我必须先单击它才能激活它,这很烦人。为了解决这个问题,我尝试了这里这里提供的解决方案,但它们不起作用。第一个链接根本没有为我做任何事情,第二个链接帮助我将master.Tk()窗口提升到前面,但这不是我需要的。我需要简单的对话框窗口成为最顶层的窗口,并且我需要它自动激活,这样当我运行我的代码并弹出屏幕时,我可以自动输入它而无需先单击它。

任何帮助将不胜感激!

我的代码:

def getUser():
    master = Tk()
    newList2=str(newList).replace(", ","\n")
    for ch in ['[',']',"'"]:
        if ch in newList2:
            newList5=newList2.replace(ch,"")
    userNr=simpledialog.askinteger("Enter user number", newList2)
    chosenUsernr= userNr - 1
    global chosenUsernrdef
    chosenUsernrdef = chosenUsernr
    master.destroy()
4

2 回答 2

1

首先,感谢 Lafexlos 通过将这样的窗口重新创建为 Tk() 实例来展示如何.lift()在 Tkinter simpledialog.askinteger() 窗口上应用和类似命令的解决方案。

然而,对于那些希望如何自动激活 Tk 窗口(因此您不必在能够输入之前单击它)的人来说,似乎有多个选项。

最常见的解决方案似乎是使用.focus().force_focus()此处此处实现。但是在这里,这些选项似乎不适用于(至少某些版本的)Windows 操作系统。这个问题显示了这些系统的可能解决方案。此外,以前的解决方案似乎不适用于多个版本的 OS X。基于此处提供的解决方案,使用 Apple 的 osascript,我能够解决我的问题。

工作代码最终如下所示:

def getUser():
    master = Tk()
    newList2=str(newList).replace(", ","\n")
    for ch in ['[',']',"'"]:
        if ch in newList2:
            newList2=newList2.replace(ch,"")
    cmd = """osascript -e 'tell app "Finder" to set frontmost of process "Python" to true'"""
    def stupidtrick():
        os.system(cmd)
        master.withdraw()
        userNr=simpledialog.askinteger("Enter user number", newList2)
        global chosenUsernrdef
        chosenUsernr= userNr - 1
        chosenUsernrdef = chosenUsernr
    stupidtrick()
    master.destroy()

简化/通用解决方案:

import os
from tkinter import Tk
from tkinter import simpledialog

def get_user():
    root = Tk()
    cmd = """osascript -e 'tell app "Finder" to set frontmost of process "Python" to true'"""
    def stupid_trick():
        os.system(cmd)
        root.withdraw()
        new_window=simpledialog.askinteger("Title of window", "Text to show above entry field")
    stupid_trick()
    root.destroy()

get_user()

编辑:现在我正在弄清楚要寻找什么解决方案似乎已经被多个帖子找到了。对于那些在 OS X 上想要在多个 Tkinter 和/或 python 实例同时运行时激活特定 Tkinter 窗口的用户,您可能需要查看此处

于 2016-11-29T21:43:22.617 回答
1

我不认为有一种方法可以提升/关注它,而askinteger只是几个小部件的组合,因此您可以轻松地自己重新创建它。

import tkinter as tk
from tkinter import messagebox

class CustomAskInteger(tk.Tk):
    def __init__(self,  numbers):
        tk.Tk.__init__(self)

        self.value = None
        self.label = tk.Label(self, text=", ".join(map(str, numbers))).pack(fill="both", expand=True)
        self.entry = tk.Entry(self)
        self.button = tk.Button(self, text="Ok", command=self.get_number)

        self.entry.pack()
        self.button.pack()

    def get_number(self):
        """
        You can customize these error handlings as you like to
        """
        if self.entry.get():
            try:
                int(self.entry.get())
                self.value = self.entry.get()
                self.destroy()
            except ValueError:
                messagebox.showwarning("Illegal Value", "Not an integer.\nPlease try again.")
        else:
            messagebox.showwarning("Illegal Value", "Not an integer.\nPlease try again.")

要在您的代码中使用它,您可以这样做

def getUser():       
    newList2=str(newList).replace(", ","\n")
    askInteger = CustomAskInteger("Enter user number", newList2)
    #since it is a Tk() instance, you can do lift/focus/grab_set etc. on this
    askInteger.lift()
    askInteger.mainloop()
    userNr = askInteger.value
于 2016-11-28T12:10:50.407 回答