I am attempting to write a Python 3 program which sets up a Gui with tkinter to display an image (in a label) and set a number of parameters via various widgets. (This part works fine.)
I want that Gui to stay on the screen while I go off and run the rest of the program which uses pygame.midi to input and output midi data. (It does not use pygame to present any screens.) (This part also works fine on its own.)
From time to time, at the control of what happens in that part of the program I want to update the Gui and/or reset some of the parameters and then go back to the midi stuff. (In other words, I'm happy to have the gui lie dormant until I tell it to wake up.) It won't work.
I've tried placing the mainloop() command at the end of the gui setup. I've tried placing it at the very end of the program. neither works. It looks to me as if the midi polling that pygame.midi does is not being allowed because both the gui and midi polling involves threads in conflict. Am I correct? Is there a simple solution? Can you point me to where I might find it?
Code added:
#!/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()
The last code listing incorporates what I learned. Basically I didn't understand the fact that the "variables" referred to in many postings as being updated were, in fact, tkinter vaiables (StringVar, BooleanVar, etc.). So python variables needed to set tkinter variables. I also thought that mainloop automatically looked for changes in tkinter variables and updated automatically. In other words, I didn't understand that I needed "trace" to be set for the variables I wanted to watch. After that, I needed to learn that "trace" doesn't update automatically, you have to use it to trigger an explicit "update". In my actual code (too long to post here) I am using tkinter variables "set" by midi events to change selections in a listbox (via "clear", "activate", "selection_set", and "see") and "update" images displayed in a label (which are linked to the index of the item selected). As far as I can tell, nothing happens automatically.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.