- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在下面的方法中,我尝试创建一个框架,将标签和文本小部件放入其中,然后将它们放入另一个文本小部件中。结果有两个问题。应该怎么改成:
建议将不胜感激!让消息按预期出现在代码中有些困难。它们应该在主小部件被拉伸(stretch)时自动换行和调整大小。
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)
该代码应该生成一个带有标签的框架以及旁边的文字换行文本。正在显示的每条新消息都应该位于旧消息之上,并且随着消息列表的增长,应该可以滚动和阅读旧消息(无限期)。不幸的是,这并不比上面的代码更好。
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)
框架似乎已正确配置,但让外部文本框充当几何管理器并设置内部文本框的高度属性似乎是这里的主要问题。外部文本框当前未调整框架大小,我不确定要根据其中的文本量编写什么代码来调整内部文本框的高度。这是程序的完整代码:
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')
最佳答案
.grid 方法对我来说要正确调整大小/拉伸(stretch)总是有点麻烦。
对于您的代码,我会将 .grid 调用更改为以下 .pack 调用:
frame.pack(expand=1, fill='both')
name.pack(fill='both', side='left')
text.pack(expand=1, fill='both')
然后您也可以放弃 .grid_{row,column}configure 调用。
您的 __text 小部件是否正确调整大小?如果它不调整大小,它也不允许此框架小部件调整大小。
关于python - 在 Python 的 tkinter 中自动调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5035824/
在 How to make a Tkinter window jump to the front? 中提出的问题之后的一个问题 我希望有一个顶层窗口(我用它来导航我的其他主窗口)总是在前面。但我希望它
有没有办法在 Tkinter 中保持小部件(特别是图像)的堆叠顺序一致?例如,我可能在 Canvas 上的同一位置有两个矩形、两个三角形和一个圆。圆圈移动到最后一次点击鼠标的地方,但我总是希望它被绘制
这是一个简单的 GUI 程序,用于创建 5x16 按钮矩阵。 from tkinter import * root = Tk() button = [[0 for x in range(16)] fo
有一个错误:“AttributeError: module 'tkinter' has no attribute 'messagebox'” 即使 import tkinter 一开始就已经给出了,为
我知道 menu.tk_popup() 可用于在特定坐标处打开上下文菜单,但也不知道如何从中打开子菜单,如果这有意义的话。这是我编写的代码: import tkinter as tk root = t
我正在尝试在禁用自动换行和水平滚动条的文本窗口中书写,如下所示: root = Toplevel() root.geometry("%dx%d+0+0" % (350,400)) af=Frame(r
已经将文本变量分配给小部件后,如何将其删除? widget.config(textvariable=None)只是不工作。在谷歌或这里找不到任何东西。 最佳答案 将您的变量分配给一个空字符串以实现此目
Jython 支持 Tkinter 吗?如果我用 Python 编写一个程序并放一个 使用 Tkinter 的 GUI 前端,做同样的事情有多难 Jython 中的程序?或者对于 Jython GUI
因此,我尝试创建一个 tkinter 窗口,显示当前时间和日期以及自定义短语。不过,我遇到的问题是,我似乎无法在第二天刷新日期。 我可以传递截至运行代码时的当前日期,但之后它变为静态。 这是我目前的程
我的理解是在初始化 __init__ 中的所有框架和小部件之后方法,tkinter 窗口会调整大小以适合所有这些组件。 我想将窗口的初始化大小设置为其最小大小。我希望能够最大化并放大窗口,但我从不希望
此代码仅水平居中,如何使进度条也垂直居中? import Tkinter import ttk root = Tkinter.Tk() root.geometry("=500x500") root.p
使用 Python 2.7 和 Tkinter 模块,我创建了一个菜单按钮并为其分配了一个菜单。现在每次我在特定位置发布菜单时,菜单的宽度都会根据字符数自动设置。有没有办法在菜单小部件中设置静态宽度?
我想将我的 tkinter 应用程序的主题更改为 clam。 代码是什么,我把它放在哪里?我试过了: from tkinter import * from tkinter.ttk import * s
我有以下代码: from Tkinter import * from urllib import urlretrieve import webbrowser import ttk def get_la
我知道,如果我将滚动条控制的框架绑定(bind)到函数 ( onFrameConfigure ),您可以获得滚动条位置,如下所示:self.calendar_frame.bind("", self.o
许多网站都说菜单小部件有一个选项“字体”,但我一直无法设置它。系统是在 Windows 8.1 中运行的 Python 3.5。脚本开始: 从 tkinter 导入 * 根 = Tk() root.g
我正在阅读本教程,它帮助我同时学习 tkinter 和 wxWidgets,但我想深入挖掘,所以想知道哪个 GUI 工具更适合深入学习,为什么? 最佳答案 不可能说哪个“更好”。两者均可用于最常见的用
看书学python,tkinter.END用在一段代码里不用解释 import tkinter def count(text, out_data): """ Update out_data w
我正在尝试使用 Python 2.7 将 Tkinter 导入到我的项目中,但我收到了错误: ImportError: No module named tkinter 在有人说之前,我已经尝试了“Tk
当我回答 Tkinter 问题时,我通常会尝试自己运行代码,但有时我会收到此错误: Traceback (most recent call last): File "C:\Python27\pyg
我是一名优秀的程序员,十分优秀!