gpt4 book ai didi

python - 使用 Tkinter,如何在启动时定位对话框或如何在设置几何图形后自动调整窗口大小?

转载 作者:太空宇宙 更新时间:2023-11-03 21:38:16 25 4
gpt4 key购买 nike

免责声明:很可能这很可能是 XY 问题,如果您能指出正确的方向,我将不胜感激。

目标:我有一个文件,我希望 tkinter 读取该文件,然后根据文件内容动态创建小部件。 我希望窗口始终以光标为中心打开。

为了 MCVE,我们考虑一个纯文本文件,内容如下:

Madness?
This
IS
T K I N T E R

tkinter 应该创建 4 个标签小部件,并调整主窗口的大小以适应。这非常简单...直到文件被加密。在读取加密文件之前,我需要 askstring()首先输入密码(MCVE:我们还假设我们只要求 key )。

我的问题:

  1. askstring对话框始终处于默认位置。我知道它应该是相对于父级(根)...

  2. 但我无法设置geometry()在创建小部件之前,它不会调整小部件的大小...

  3. 而且我无法预先确定 geometry() 所需的大小因为没有密码( key )我无法打开文件...

这是我最成功的尝试的 MCVE 示例:

import tkinter as tk
from tkinter.simpledialog import askstring
from cryptography.fernet import Fernet

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

# side note: If I don't withdraw() the root first, the dialog ends up behind the root
# and I couldn't find a way to get around this.
self.withdraw()
self.create_widgets()

# Attempt: I tried doing this instead of self.create_widgets():
# self.reposition()
# self.after(ms=1,func=self.create_widgets)
# The dialog is positioned correctly, but the window size doesn't resize

self.deiconify()

# I have to do the reposition AFTER mainloop or else the window size becomes 1x1
self.after(ms=1, func=self.reposition)
self.mainloop()

def get_key(self):
return askstring('Locked','Enter Key', show='*', parent=self)

def create_widgets(self):
self.lbls = []
with open('test2.txt', 'rb') as file:
encrypted = file.read()
key = self.get_key()
suite = Fernet(key)
self.data = suite.decrypt(encrypted).decode('utf-8')
for i in self.data.split('\n'):
self.lbls.append(tk.Label(self, text=i.strip()))
self.lbls[-1].pack()

def reposition(self):
width, height = self.winfo_width(), self.winfo_height()
self.geometry(f'{width}x{height}+{self.winfo_pointerx()-int(width/2)}+{self.winfo_pointery()-int(height/2)}')

gui = GUI()

实现了什么(我可以忍受):

  • ✓ 根据文件内容修正大小
  • ✓ 根位于光标中心
  • ⨯ 提示在光标中心输入按键

我的问题是:

  1. 是否可以基于类似于pack_propagate()的widgets功能再次在根上执行自动调整大小之后geometry()已设置?好像有一次geometry()设置后根将不再传播。

  2. 如果没有,我如何在代码中手动调整它的大小?我尝试检索小部件的总高度 height = sum([i.winfo_reqheight() for i in self.lbls])但是height就变成 0 。但是当我 print(self.lbls[-1].winfo_reqheight())self.create_widgets()它返回26每个,他们实际上打印之后我的 self.reposition()打电话,这很奇怪。

  3. 如果做不到这一点,是否可以定位 askstring()创建小部件之前的对话框?

我被难住了。我觉得我的处理方式是错误的,但我不确定处理这种情况以打破依赖循环的正确方法是什么。

<小时/>

为了帮助重现这里的加密字符串以及 key :

数据:

gAAAAABb2z3y-Kva7bdgMEbvnqGGRRJc9ZMrt8oc092_fuxSK1x4qlP72aVy13xR-jQV1vLD7NQdOTT6YBI17pGYpUZiFpIOQGih9jYsd-u1EPUeV2iqPLG7wYcNxYq-u4Z4phkHllvP

关键:

SecretKeyAnyhowGoWatchDareDevilS3ItsAmazing=

编辑:基于@BryanOakley's answer here我可以调用self.geometry("")重置,但它会返回到 native 200x200大小,但仍然不传播小部件。

最佳答案

经过数十次尝试,我想我已经成功了,以下是我修改的相关部分:

def __init__(self):
super().__init__()
self.withdraw()

# reposition the window first...
self.reposition()

# For some reason I can't seem to figure out,
# without the .after(ms=1) the dialog still goes to my top left corner
self.after(ms=1, func=self.do_stuff)
self.mainloop()

# wrap these functions to be called by .after()
def do_stuff(self):
self.create_widgets()
self.deiconify()

def reposition(self):
width, height = self.winfo_width(), self.winfo_height()
self.geometry(f'{width}x{height}+{self.winfo_pointerx()-int(width/2)}+{self.winfo_pointery()-int(height/2)}')

# reset the geometry per @BryanOakley's answer in the linked thread
# Seems it resets the width/height but still retains the x/y
self.geometry("")

它会出现@BryanOakley have answers对于 tkinter 的所有事情。

我仍在等待是否会有其他人参与这个主题,并且很乐意接受您的回答以澄清该主题。

关于python - 使用 Tkinter,如何在启动时定位对话框或如何在设置几何图形后自动调整窗口大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53106176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com