Ali-RNT Ответов: 1

Фотоизображение не отображается в новом окне-использование Python tkinter


Я пишу программу, которая запрашивает строку и код, открывает новое окно и показывает строку как светодиодный текст. на данный момент, чтобы проверить это, я написал его таким образом, что новое окно рисует синус, но оно не отображается. При выполнении кода в _ _ init_ _ функция класса LED работает хорошо.

Что я уже пробовал:

from Tkinter import *
import time
from math import sin
STEPTIME = 0.50
WIDTH = 200
HEIGHT = 20
class App:
	def __init__(self, master):
		#Initialize Data Panel
		self.dataFrame = Frame(master)
		self.stringLabel = Label(self.dataFrame, text="Enter a string: ")
		self.stringBox = Text(self.dataFrame, height=1, width=30)
		self.codeLabel = Label(self.dataFrame, text="Enter display code: ")
		self.codeBox = Text(self.dataFrame, height=1, width=5)
		self.dataFrame.pack(padx=5 ,pady=10 , side=LEFT)
		self.stringLabel.pack()
		self.stringBox.pack()
		self.codeLabel.pack()
		self.codeBox.pack()
		
		#Initialize Button panel
		self.buttonFrame = Frame(master)
		self.button = Button(self.buttonFrame, text="Run", command=self.run)
		self.buttonFrame.pack(padx=5 ,pady=20 , side=RIGHT)
		self.button.pack()

	def run(self):
		string = self.getString()
		code = self.getCode()
		root = Tk()
		led = LED(root)
		root.mainloop()
		
	def getString(self):
		string = self.stringBox.get("1.0", "end-1c")
		return string
		
	def getCode(self):
		code = self.codeBox.get("1.0", "end-1c")
		return code
		
class LED:
	def __init__(self, master):
		WIDTH, HEIGHT = 200, 200
		canvas = Canvas(master, width=WIDTH, height=HEIGHT, bg="#000000")
		canvas.pack()
		img=PhotoImage(master = canvas, width=WIDTH, height=HEIGHT)
		canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")
		for x in range(4 * WIDTH):
			y = int(HEIGHT/2 + HEIGHT/4 * sin(x/80.0))
			img.put("#ffffff", (x//4,y))
		
root = Tk()
app = App(root)
root.mainloop()

Richard MacCutchan

Я не использовал Tk с Python, но я заметил, что вы звоните root.mainloop во второй раз, изнутри App.run метод. Правильно ли это?

Ali-RNT

Нет,я так не думаю, потому что новое окно создано. А второй корень находится в классе приложений и не мешает корню, определенному в основном коде.

Richard MacCutchan

Значит, это создает второе окно? Я думаю, что мне нужно изучить ТЗ для себя.

Richard MacCutchan

Я перепробовал столько вариантов, сколько смог придумать в приведенном выше коде, включая прямой вызов светодиода, различные значения для x и y, но не смог получить ни одного пикселя, нарисованного на изображении. Однако, когда я попробовал небольшой пример кода, который я нашел в http://tkinter.unpythonic.net/wiki/PhotoImage это сработало правильно.

1 Ответов

Рейтинг:
5

Richard MacCutchan

Проблема была вызвана тем, что img объект был собран мусором после того, как LED.__init__ метод завершен, поэтому холст оказался пустым. Добавление чего-то вроде дополнительной строки ниже удерживает его на месте.

img=PhotoImage(master = canvas, width=WIDTH, height=HEIGHT)
canvas.create_image((WIDTH/2, HEIGHT/2), image=img, state="normal")
canvas.theimage = img # add attribute to prevent GC


Ali-RNT

Спасибо за время, которое вы потратили на этот вопрос. Это сработало!

Richard MacCutchan

Это был интересный вызов.