python - tkinter:如何让标签的子类显示在屏幕上?
问题描述
我正在尝试用 Python 中的类做一些事情(我来自过程语言背景)。尝试创建一个版本的 tkinterLabel
小部件,支持几种新方法来操作标签的文本。
我的问题是我无法让标签在屏幕上实际可见。
这是代码:
from tkinter import *
DEFAULT_BG = '#f0f0f0'
class cngMsg(Label):
"""Message Display label"""
def __init__(self, parent, w, h):
"""Init the Message Label"""
self.parent = parent
Label.__init__(self, parent)
self.msgText = "Hello World"
self.msgLabel = Label(parent, text=self.msgText)
self.msgLabel.config(height=h, width=w, bg=DEFAULT_BG)
def clear(self):
self.msgText = ""
print(len(self.msgText))
self.msgLabel.config(text=self.msgText)
def newMessage(self, message):
print("about to display <" + message + ">")
self.msgText = message
print(len(self.msgText))
self.msgLabel.config(text=self.msgText)
def show(self, message, sameLine=None):
if (not sameLine) and len(self.msgText) > 0:
self.msgText += '/n'
print("about to show: <" + message + ">")
self.msgText = self.msgText + message
print(len(self.msgText))
self.msgLabel.config(text=self.msgText)
#Root Stuff
if __name__ == "__main__":
app = Tk()
app.title("Message Test")
# this is the start of the application
print("initialise the Message Test")
gMsg = cngMsg(app, 60, 20)
gMsg.pack()
gMsg.newMessage("new message")
gMsg.show("this is a test")
gMsg.show("second test")
app.mainloop()
调试打印消息出现在控制台上,但应用程序窗口不显示标签。
解决方案
GUI 编程需要使用非过程范式,因为它们是用户输入驱动的。问题Tkinter — execution functions over time讨论了这一点并有一些示例代码。
就我个人而言,我经常发现在创建 GUI 应用程序时将它们视为 FSM(有限状态机)很有用,其中用户输入会导致它们改变状态。
这是基于@Bryan Oakley 对链接问题的回答(更新到 Python 3)的示例代码中我认为您尝试执行的操作的方法。它还显示了对类进行子tkinter
类化的正确方法。此外,它主要遵循PEP 8 - Python 代码样式指南,我强烈建议您阅读并开始遵循。
from tkinter import *
DEFAULT_BG = '#f0f0f0'
DEFAULT_MSG_TEXT = "Hello World"
DELAY = 1000 # Milliseconds.
class CngMsg(Label):
"""Message Display label"""
def __init__(self, parent, w, h):
# Intialize with default text and background color.
super().__init__(parent, text=DEFAULT_MSG_TEXT, height=h, width=w, bg=DEFAULT_BG)
def clear(self):
self.config(text='')
def newMessage(self, message):
self.config(text=message)
def show(self, message, same_line=False):
text = self.cget('text') # Get value of current option.
if not same_line and text:
text += '\n'
text += message
self.config(text=text)
class MyApp(Tk):
def __init__(self):
super().__init__()
self.frame = Frame(self)
self.frame.pack()
self.test_msg = CngMsg(self.frame, 60, 20)
self.test_msg.pack()
self.state = 0
self.do_test()
def do_test(self):
if self.state == 0:
self.test_msg.newMessage("start message")
self.state = 1
elif self.state == 1:
self.test_msg.show("this is a test")
self.state = 2
elif self.state == 2:
self.test_msg.show("second test")
self.state = 3
elif self.state == 3:
self.test_msg.clear()
self.test_msg.show("TEST COMPLETED")
self.state = -1 # Enter final state.
elif self.state != -1:
self.quit() # Stop mainloop.
raise RuntimeError("Unknown state encountered")
if self.state != -1: # Not final state?
self.after(DELAY, self.do_test) # Schedule another call.
if __name__ == "__main__":
root = MyApp()
root.title("Message Test")
root.mainloop()
推荐阅读
- r - R - 检查错误消息是否是由于缺少参数
- php - 尝试将选定的行从 db 插入新表
- typescript - 为泛型函数分配类型
- wordpress - 从产品列表创建 WooCommerce 订单——批量操作
- vb.net - 合并两个没有任何重复的数组 [VB.NET]
- python - Smartsheet python SDK添加带有单元格链接的行
- html - 构建 HTML/CSS 页面但无法加载图像
- php - Test Mail Server 和 Papercut 需要 php.ini sendmail_from 吗?
- javascript - 如何使用 node.js 正确使用/下载声音并通过客户端播放?
- c# - 在为自定义 DataGridViewColumn 设置属性时访问 DataGridView 控件