I'm having trouble playing a video and moving to the next frame by clicking on one button. The problem is that the video starts playing at the beginning of the GUI, meaning that it has ended once you get to the right frame. I've tried to solve this by defining a function that only actually plays the video once the button is clicked. I can get it to move to the next frame and even print that the function is working but it won't play the video. To complicate things a bit, I've been working from different files and in classes. I've tried to slim down as much as possible with the following MWE:
page 1
as an overview page
page 2
as a first frame with the button
page 3
as a second frame with the MP4
page1
:
import tkinter as tk
from tkinter import *
from page2 import *
######Ensuring that the frames don't load as seperate windows but as frames over one another#######
class GUI(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
# create a container for all the widgets (buttons, etc)
window = Frame(self)
window.pack(side="top", fill="both", expand=True)
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)
self.frames = {}
# for loops for switching between pages
for F in (Page2, Page3):
frame = F(window, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Page2)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
if __name__ == "__main__":
window = GUI()
window.geometry("400x400")
window.mainloop()
page2
:
import tkinter as tk
from tkinter import *
from page3 import *
class Page2(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
DF = Listbox(self, bg='#f8f8f8',height=30, width=70, highlightthickness=0, borderwidth=0)
DF.place(x=0, y=0)
nextpage = Page3(parent, controller)
play = nextpage.play_video
button = Button(
DF,
text="press",
bg='#ffffff',
height=4,
width=30,
command=lambda: [controller.show_frame(Page3),play.play_video()],
)
button.place(relx=0.5, rely=0.5, anchor=CENTER)
page3
:
import tkinter as tk
from tkinter import *
from tkVideoPlayer import TkinterVideo
class Page3(Frame):
def __init__(self, parent, controller):
Frame.__init__(self, parent)
DF2 = Listbox(self, bg='green',height=30, width=70, highlightthickness=0, borderwidth=0)
DF2.place(x=0, y=0)
self.vid_player = TkinterVideo(DF2, scaled = True)
self.vid_player.place(x=0, y=0)
self.vid_player.load("Location_of_MP4.mp4")
###add this to play the MP4###
#self.vid_player.play()
def play_video(self):
print("working")
self.vid_player.play()
If you add the self.vidplayer.play()
part you can tell that the MP4 isn't having problems. Just opening it from the function play_video
seems to be not working.
I'm a bit stuck as I've tried a number of work-arounds to fix the issue. I'm flexible in the solution, e.g. it doesn't have to be a function to play the video. If possible it could also be played directly from the command=lambda
or any other way. I've also tried to look for code that would reset the video to the start but haven't found that either.
After some time I've found a solution. In file two change the button command to a single function command
command=lambda:self.Function(controller),
Within that Function create a thread to simultaneously redirect to the 3rd page while also running a simulation. After the simulation redirect to the other frame
def FuncD(self, cont):
cont.show_frame(page3)
def thread_function(name):
self.runcase()
time.sleep(5)
cont.show_frame(UC_Power2Plug_Results)
thread = threading.Thread(target=thread_function, args=(1,))
thread.start()
This should solve the one click two command issue. Add the following line to keep the video going
self.vid_player.bind("<<Ended>>",self.video_ended)
With this function behind the line of command
def video_ended(self, event=None):
""" handle video ended """
videoplayer = self.vid_player
videoplayer.play()