我正在尝试编写一个Python 3程序,该程序使用tkinter设置Gui来显示图像(在标签中) 并通过各种小部件设置许多参数。 (这部分工作正常。)
我想让Gui在我离开并运行使用pygame.midi的程序的其余部分时留在屏幕上 输入和输出MIDI数据。 (它不使用pygame来显示任何屏幕。)(这部分在其上也可以正常工作 自己的。)
我不时要控制程序那部分中发生的事情,以便更新Gui和/或重置 一些参数,然后再回到midi的东西。 (换句话说,我很高兴让gui lie处于休眠状态,直到我 告诉它醒来。)它将不起作用。
我尝试将mainloop()命令放在gui设置的末尾。我尝试将其放在程序的最后。 都不起作用。在我看来,不允许pygame.midi进行的midi轮询是因为gui和midi 轮询涉及冲突线程。我对么?有没有简单的解决方案?您能指出我可能找到的地方吗?
已添加代码:
#!/usr/local/bin/python3
from tkinter import Tk
from tkinter import ttk
from tkinter import Frame
from tkinter import E, W
from tkinter import StringVar
import sys
import os
import pygame.midi
def do_nothing(*args):
labelbox.update()
def do_midi():
global pygame_initialized, midi_out, midi_in, msgVar
if not pygame_initialized:
pygame.init()
pygame.midi.init() # Sets PortMidi timer to zero.
midi_in = pygame.midi.Input(3, 4096)
midi_out = pygame.midi.Output(2)
pygame_initialized = True
midi_out.write_short(176, 122, 00) # turn off echo
while True:
if midi_in.poll():
midi_event_list = midi_in.read(1)
event = midi_event_list[0][0][0]
if event == 248: # timing event ignore
continue
if event > 159 or event < 128: # non key-off or key-on midi events are passed through
midi_out.write(midi_event_list)
continue
# From here on we are dealing only with key-on or key-off events
key = midi_event_list[0][0][1]
vel = midi_event_list[0][0][2]
if key == 21: # right now this is the only way back to the gui to Quit
if vel != 0:
midi_out.write_short(176, 122, 127) # Turn local control back on
return
if vel != 0: # only do this for key-on events
msgVar.set(key)
midi_out.write_short(event, key, vel)
def cleanup():
global pygame_initialized, midi_out, midi_in
root.destroy()
if pygame_initialized:
del midi_out
del midi_in
pygame.midi.quit()
sys.exit()
if __name__ == '__main__':
os.environ['SDL_VIDEO_WINDOW_POS'] = "%d,%d" % (0, 0)
pygame_initialized = False
global msgVar
message = "Push the Play button!"
root = Tk()
msgVar = StringVar()
msgVar.set(message)
msgVar.trace("w", do_nothing)
root.title("Testing midi")
root.geometry("900x600+200+100")
frame1 = Frame(root, width=900, height=600)
frame1.grid(column=0, row=0)
ttk.Button(frame1, text="Play", style='My.TButton', command=do_midi).grid(column=0, row=4, pady=(40, 0), sticky=W)
labelbox = ttk.Label(frame1)
labelbox.grid(column=1, row=4)
labelbox.configure(textvariable=msgVar)
ttk.Button(frame1, text="Quit", style='My.TButton', command=cleanup).grid(column=2, row=4, pady=(40, 0), sticky=E)
root.mainloop()
答案 0 :(得分:1)
最后的代码清单包含了我学到的东西。基本上,我不理解许多帖子中提到的“变量”实际上是更新的,它们是tkinter变量(StringVar,BooleanVar等)。因此,需要使用python变量来设置tkinter变量。我还认为mainloop会自动查找tkinter变量中的更改并自动更新。换句话说,我不明白我需要为想要监视的变量设置“跟踪”。之后,我需要了解“跟踪”不会自动更新,您必须使用它来触发显式的“更新”。 在我的实际代码中(太长,无法在此处发布),我正在使用midi事件的tkinter变量“ set”来更改列表框中的选择(通过“ clear”,“ activate”,“ selection_set”和“ see”)和“ update”标签中显示的图片(链接到所选项目的索引)。据我所知,什么也不会自动发生。