[英]conflicts between tkinter and pygame.midi
我正在尝试编写一个 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()
最后一个代码清单包含了我学到的东西。 基本上我不明白在许多帖子中提到的“变量”被更新的事实,实际上是 tkinter 变量(StringVar、BooleanVar 等)。 所以python变量需要设置tkinter变量。 我还认为 mainloop 会自动查找 tkinter 变量中的更改并自动更新。 换句话说,我不明白我需要为我想观察的变量设置“跟踪”。 在那之后,我需要了解“跟踪”不会自动更新,您必须使用它来触发显式“更新”。 在我的实际代码(太长,无法在此处发布)中,我使用 tkinter 变量通过 MIDI 事件“设置”来更改列表框中的选择(通过“清除”、“激活”、“selection_set”和“查看”)和“更新” " 显示在标签中的图像(链接到所选项目的索引)。 据我所知,没有任何事情会自动发生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.