0

この関数は、Tkinter のシンプルなダイアログ画面を表示して簡単なユーザー入力を要求する Python スクリプトの 1 つに含まれています。機能は動作します。ただし、これには2 つの問題があります。

  1. 2 つのウィンドウが開きますが、必要なのは 1 つだけです。しかし、 master = Tk()を削除すると、エラーが発生します。

AttributeError: 'NoneType' オブジェクトには属性 'winfo_viewable' がありません

ある時点でそれを理解するのはいいことですが、私の主な問題は2番目のものです:

  1. シンプルなダイアログ画面が表示されるたびに、アクティブになる前に最初にクリックする必要があり、面倒です。それを修正するために、ここここで提供されている解決策を試しましたが、うまくいきません。最初のリンクは何もしませんでした.2番目のリンクは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

.lift()まず、 Tk() インスタンスとしてそのようなウィンドウを再作成することによって、Tkinter simpledialog.askinteger() ウィンドウに適用する方法と同様のコマンドの解決策を示した Lafexlos の功績です。

ただし、Tk ウィンドウを自動的にアクティブにする方法を探している人には (入力する前にクリックする必要はありません)、複数のオプションがあるようです。

最も一般的な解決策は、.focus()or.force_focus()を使用することあると思われます。ただし、ここでは、これらのオプションが (少なくとも一部のバージョンの) Windows OS では機能しない可能性があるようです。この質問は、それらのシステムの可能な解決策を示しています。また、以前の解決策は、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 に答える