【问题标题】:Python TksimpleDialog positioning next to the root windowPython TksimpleDialog 定位在根窗口旁边
【发布时间】:2017-02-27 13:08:33
【问题描述】:

我正在尝试打开一个简单的对话窗口,用户可以在其中输入基于根窗口上显示的菜单的选项。但是,当我运行代码时,对话框会直接在根窗口中的菜单上方打开,从而使其看不见。有没有办法打开对话框,以便它在根窗口旁边打开,如附图所示。

我已经检查了这个link,它似乎没有任何简单对话框的定位参数。我也尝试过使用顶层,但是打开多个窗口会变得很乱。

我的代码如下:

from Tkinter import *
import tkSimpleDialog

root = Tk()
root.lift()


Label(root, text = "Menu Choices:").grid(row=1, column =0)
Label(root, text='1. Baloney and cheese').grid(row=2, column=0, pady=4)
Label(root, text='2. Roast chicken and gravy').grid(row=3, column=0, pady=4)
Label(root, text='3. Pear salad').grid(row=4, column=0, pady=4)
Label(root, text='4. Cateloupe and brocoli soup').grid(row=5, column=0, pady=4)

people = ["Liam","Henry","Paula"]

menuChoice = []

for i in people:
    c = tkSimpleDialog.askinteger('Franks Restaurant', 'Please choose your meal?', parent = root)
    menuChoice.append(c)

root.mainloop()

【问题讨论】:

  • 这是从用户那里获取输入的一种非常奇怪的方式,而不是 GUI 的设计工作方式。为什么不制作菜单选择按钮或单选按钮,完全避免对话框?
  • 您应该只在主窗口中添加一个条目或一个列表框。
  • @BryanOakley + Dashadower 感谢您的 cmets,但这只是我想生成弹出窗口和分配的问题的一个示例。正如您所说,也许最好在根屏幕上显示所有信息,但是当我遍历选项列表然后使用选项更新字典条目时,我决定这样做。也许只是不可能将一个简单的对话框锚定到根窗口的一侧.....
  • @Bryan,使用 tkSimpleDialog 是否是一个好习惯,是另一个问题。这里的问题非常简单,可以简化为:“我怎样才能将 tkSimpleDialog 定位在我想要的位置?”这是一个有效且非常好的问题。我也有同样的问题。
  • @alkey,你的问题是一个百万美元的问题! :) 这是我经过长期研究得出的结论,其中我在另外 3 个地方发现了同样的问题,但未得到解答。真正令人讨厌的是对话框是随机放置的,通常靠近屏幕的左上角。他们至少可以放在中心位置!

标签: python python-2.7 tkinter


【解决方案1】:
  • 这是一个相对于主窗口定位对话框的示例。
  • 每次打开对话框时,它都会跟踪根窗口的位置。
  • 它使用几何来设置对话框的左侧和顶部位置

'

import tkinter as tk

try:  # allows the text to be more crisp on a high dpi display
  from ctypes import windll
  windll.shcore.SetProcessDpiAwareness(1)
except:
  pass

# ----------------------------------------------------------------------------
class CustomDialog:
    def __init__(self, parent):
        self.top = tk.Toplevel(parent)

        xPos = root.winfo_x()
        yPos = root.winfo_y()
        posStr = "+" + str(xPos + 160) + "+" + str(yPos)
        self.top.geometry(posStr)

        tk.Label(self.top, text="Dlg is positioned relative to root window.").pack()
        tk.Button(self.top, text="Ok", command=self.Ok).pack()

    def Ok(self):
        self.top.destroy()

# ----------------------------------------------------------------------------
def onOpenDlg():
    inputDialog = CustomDialog(root)
    root.wait_window(inputDialog.top)

# ----------------------------------------------------------------------------
root = tk.Tk()
tk.Label(root, text="Position Dlg Example").pack()
tk.Button(root, text="Open Dlg", command=onOpenDlg).pack()

root.mainloop()

'

【讨论】:

  • 如果你可以将tkinter 改为Tkinter 会很酷,因为 OP 使用 python 2.x 和其他必要的更改
  • 酷云好点。我没有注意到 2.x 在 OP 中的使用。
【解决方案2】:

Tk 库实际上具有执行此操作的功能,尽管它名义上是“私有的”。您可以按如下方式使用它。

import tkinter as tk

root = tk.Tk()
root.wm_geometry("800x600")
dialog = tk.Toplevel(root)
root_name = root.winfo_pathname(root.winfo_id())
dialog_name = dialog.winfo_pathname(dialog.winfo_id())
root.tk.eval('tk::PlaceWindow {0} widget {1}'.format(dialog_name, root_name))
root.mainloop()

这会将您的对话框置于指定窗口的中心(在本例中为根窗口)。

【讨论】:

    【解决方案3】:

    一种方法是使用顶级小部件。而且一点也不乱。无论如何,要将输入框架放置在您想要的位置,您必须首先设置主(根)框架的尺寸和位置:

    from Tkinter import *
    import ttk
    
    root = Tk()
    root.lift()
    w = 300; h = 200; x = 10; y = 10
    root.geometry('%dx%d+%d+%d' % (w, h, x, y))
    
    Label(root, text = "Menu Choices:").grid(row=1, column =0)
    Label(root, text='1. Baloney and cheese').grid(row=2, column=0, pady=4)
    Label(root, text='2. Roast chicken and gravy').grid(row=3, column=0, pady=4)
    Label(root, text='3. Pear salad').grid(row=4, column=0, pady=4)
    Label(root, text='4. Cateloupe and brocoli soup').grid(row=5, column=0, pady=4)
    
    def store_entry():
      print "Entry stored as "+ent.get()
    
    def exit_entry():
      print "Entry cancelled"
      top.destroy()
    
    top = Toplevel()
    top.title('Franks Restaurant')
    top.geometry("%dx%d+%d+%d" % (w, h, w+x+20, y))
    Label(top, text='Please choose your meal').place(x=10,y=10)
    ent = Entry(top); ent.place(x=10, y=50); ent.focus()
    Button(top, text="OK", command=store_entry).place(x=10, y=150) 
    Button(top, text="Cancel", command=exit_entry).place(x=60, y=150)  
    
    root.mainloop()
    

    这是一个将用户输入窗口放置在您想要的位置的示例。您需要实现它以验证和存储用户输入,并根据需要为尽可能多的用户提供服务。

    【讨论】:

      猜你喜欢
      • 2016-01-29
      • 2015-07-15
      • 2012-06-27
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2015-06-29
      • 1970-01-01
      • 2012-07-08
      相关资源
      最近更新 更多