Dans la méthode suivante, j'essaie de créer un cadre, y mettre une étiquette et un widget de texte, et les placer à l'intérieur d'un autre widget de texte. Il y a deux problèmes avec les résultats. Comment devrait-il être changé en:Redimensionnement automatique dans le tkinter de Python
- Les objets de texte interne ont-ils la bonne hauteur en fonction du texte inséré?
- Obtenez le cadre et le texte à redimensionner aux dimensions actuelles du widget externe?
Des suggestions seraient appréciées! Il est quelque peu difficile d'afficher les messages comme prévu dans le code. Ils sont censés être automatiquement enveloppés et redimensionnés lorsque le widget principal est étiré.
def display(self, name, message):
frame = tkinter.ttk.Frame(self.__text, borderwidth=1)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(1, weight=1)
name = tkinter.ttk.Label(frame, text=name)
name.grid(row=0, column=0)
text = tkinter.Text(frame, wrap=tkinter.WORD, height=1)
text.grid(row=0, column=1, sticky=tkinter.EW)
text.insert('1.0', message)
text.configure(state=tkinter.DISABLED)
self.__text.window_create('1.0', window=frame, stretch=tkinter.TRUE)
Le code est censé générer une trame avec une étiquette à côté de celui-ci. Chaque nouveau message affiché doit être placé au-dessus des messages les plus anciens et, à mesure que la liste des messages augmente, il devrait être possible de faire défiler et de lire les messages plus anciens (indéfiniment). Malheureusement, cela ne fonctionne pas mieux que le code ci-dessus.
def display(self, name, message):
frame = tkinter.ttk.Frame(self.__text, borderwidth=1, relief='solid')
name = tkinter.ttk.Label(frame, text=name)
text = tkinter.Text(frame, wrap=tkinter.WORD, height=1)
frame.pack(expand=tkinter.TRUE, fill=tkinter.BOTH)
name.pack(fill=tkinter.BOTH, side=tkinter.LEFT)
text.pack(expand=tkinter.TRUE, fill=tkinter.BOTH)
text.insert('1.0', message)
text.configure(state=tkinter.DISABLED)
self.__text.window_create('1.0', window=frame)
Le cadre semble être correctement configuré, mais obtenir la zone de texte externe pour agir comme un gestionnaire de géométrie et définissant la propriété de hauteur de la zone de texte intérieur semblent être les principaux problèmes ici. La zone de texte externe ne redimensionne pas actuellement le cadre, et je ne suis pas sûr du code à écrire pour redimensionner la hauteur de la zone de texte interne en fonction de la quantité de texte à l'intérieur de celle-ci. Voici le code complet du programme:
import tkinter
import tkinter.ttk
import datetime
import getpass
import os
import uuid
################################################################################
class DirectoryMonitor:
def __init__(self, path):
self.__path = path
self.__files = {}
def update(self, callback):
for name in os.listdir(self.__path):
if name not in self.__files:
path_name = os.path.join(self.__path, name)
self.__files[name] = FileMonitor(path_name)
errors = set()
for name, monitor in self.__files.items():
try:
monitor.update(callback)
except OSError:
errors.add(name)
for name in errors:
del self.__files[name]
################################################################################
class FileMonitor:
def __init__(self, path):
self.__path = path
self.__modified = 0
self.__position = 0
def update(self, callback):
modified = os.path.getmtime(self.__path)
if modified != self.__modified:
self.__modified = modified
with open(self.__path, 'r') as file:
file.seek(self.__position)
text = file.read()
self.__position = file.tell()
callback(self.__path, text)
################################################################################
class Aggregator:
def __init__(self):
self.__streams = {}
def update(self, path, text):
if path not in self.__streams:
self.__streams[path] = MessageStream()
parts = text.split('\0')
assert not parts[-1], 'Text is not properly terminated!'
self.__streams[path].update(parts[:-1])
def get_messages(self):
all_messages = set()
for stream in self.__streams.values():
all_messages.update(stream.get_messages())
return sorted(all_messages, key=lambda message: message.time)
################################################################################
class MessageStream:
def __init__(self):
self.__name = None
self.__buffer = None
self.__waiting = set()
def update(self, parts):
if self.__name is None:
self.__name = parts.pop(0)
if self.__buffer is not None:
parts.insert(0, self.__buffer)
self.__buffer = None
if len(parts) & 1:
self.__buffer = parts.pop()
for index in range(0, len(parts), 2):
self.__waiting.add(Message(self.__name, *parts[index:index+2]))
def get_messages(self):
messages = self.__waiting
self.__waiting = set()
return messages
################################################################################
class Message:
def __init__(self, name, timestamp, text):
self.name = name
self.time = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%SZ')
self.text = text
################################################################################
class MessageWriter:
def __init__(self, path, name):
assert '\0' not in name, 'Name may not have null characters!'
self.__name = str(uuid.uuid1())
self.__path = os.path.join(path, self.__name)
with open(self.__path, 'w') as file:
file.write(name + '\0')
@property
def name(self):
return self.__name
def write(self, text):
assert '\0' not in text, 'Text may not have null characters!'
timestamp = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%SZ')
with open(self.__path, 'a') as file:
file.write(timestamp + '\0' + text + '\0')
################################################################################
class Logos(tkinter.ttk.Frame):
@classmethod
def main(cls, path):
tkinter.NoDefaultRoot()
root = tkinter.Tk()
root.title('Logos 2.0')
root.minsize(320, 240) # QVGA
view = cls(root, path)
view.grid(row=0, column=0, sticky=tkinter.NSEW)
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)
root.mainloop()
def __init__(self, master, path, **kw):
super().__init__(master, **kw)
self.configure_widgets()
self.__writer = MessageWriter(path, getpass.getuser())
self.__monitor = DirectoryMonitor(path)
self.__messages = Aggregator()
self.after_idle(self.update)
def configure_widgets(self):
# Create widgets.
self.__text = tkinter.Text(self, state=tkinter.DISABLED)
self.__scroll = tkinter.ttk.Scrollbar(self, orient=tkinter.VERTICAL,
command=self.__text.yview)
self.__entry = tkinter.ttk.Entry(self, cursor='xterm')
# Alter their settings.
self.__text.configure(yscrollcommand=self.__scroll.set)
# Place everything on the grid.
self.__text.grid(row=0, column=0, sticky=tkinter.NSEW)
self.__scroll.grid(row=0, column=1, sticky=tkinter.NS)
self.__entry.grid(row=1, column=0, columnspan=2, sticky=tkinter.EW)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
# Setup box for typing.
self.__entry.bind('<Control-Key-a>', self.select_all)
self.__entry.bind('<Control-Key-/>', lambda event: 'break')
self.__entry.bind('<Return>', self.send_message)
self.__entry.focus_set()
def select_all(self, event):
event.widget.selection_range(0, tkinter.END)
return 'break'
def send_message(self, event):
text = self.__entry.get()
self.__entry.delete(0, tkinter.END)
self.__writer.write(text)
def update(self):
self.after(1000, self.update)
self.__monitor.update(self.__messages.update)
for message in self.__messages.get_messages():
self.display(message.name, message.text)
def display(self, name, message):
frame = tkinter.ttk.Frame(self.__text, borderwidth=1, relief='solid')
name = tkinter.ttk.Label(frame, text=name)
text = tkinter.Text(frame, wrap=tkinter.WORD, height=1)
name.grid(row=0, column=0)
text.grid(row=0, column=1, sticky=tkinter.EW)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(1, weight=1)
text.insert('1.0', message)
text.configure(state=tkinter.DISABLED)
self.__text.window_create('1.0', window=frame)
################################################################################
if __name__ == '__main__':
Logos.main('Feeds')
Merci de demander les exigences! Ils ont été ajoutés ci-dessus. –
Il est clair que la question doit être re-posée que les demandes d'aide avec des problèmes plus petits. –