只是为了回答我的问题,以防有人遇到类似的问题。
事实证明使用Kivynot对我来说可行有两个原因:
-
虽然可以像示例中那样使 kivy 应用程序透明https://github.com/kivy/kivy/pull/5252 https://github.com/kivy/kivy/pull/5252它需要一个模板图像来完成。由于我希望我的应用程序在不同尺寸的屏幕上运行,并且我对生成图像一无所知,因此我决定不使用此方法。
-
将按钮应用程序缩小,使其仅覆盖视频的一部分,效果很好。这变得有问题,因为视频使用另一个程序运行,这意味着视频将在应用程序前面打开,并且我会失去控制,直到我专门单击该应用程序。在 Windows 上可以通过启动视频然后延迟生成按钮或在创建视频屏幕后最小化并重新打开应用程序来克服此问题。不幸的是,这种方法并没有转化为单板计算机,以最大化视频播放性能我没有使用桌面环境,只使用X Window系统(X11),即使使用基本的窗口管理器,我也遇到了很多最小化和最大化的困难视窗。
我的解决方案是转向 Tkinter,因为它能够强制窗口位于前面并且可以使其透明。下面是 Tkinter 中的等效代码,虽然它尚未完成,但它具有我在原始问题中提到的功能:
from functools import partial
import tkinter as tk
import threading
import time
import vlc
global videoscreen_button_num
videoscreen_button_num = 0
global button_timer
global show_button
button_timer = 0
show_button = False
class video_window:
def __init__(self, master, channel): #create the windows
self.master = master
self.frame = tk.Frame(self.master)
reset_encoder = tk.Button(self.frame, text = 'Reset Encoder', width = 25, command = self.close_windows) #create buttons to control the video
reset_video = tk.Button(self.frame, text = 'Refresh Video', width = 25, command = self.close_windows)
return_button = tk.Button(self.frame, text = 'Return to Main Menu', width = 25, command = self.close_windows)
return_button.grid(row=0, column=0)
reset_video.grid(row=0, column=1)
reset_encoder.grid(row=0, column=2)
unselected_colour = "SteelBlue1"
selected_colour = "RoyalBlue1"
return_button.config(background = selected_colour)
reset_video.config(background = unselected_colour)
reset_encoder.config(background = unselected_colour)
self.frame.pack()
self.video_button_ids = []
self.video_button_ids.append(reset_encoder)
self.video_button_ids.append(reset_video)
self.video_button_ids.append(return_button)
Instance = vlc.Instance() #'--verbose 2'.split())
self.player = Instance.media_player_new()
Media = Instance.media_new(channel)
Media.get_mrl()
self.player.set_media(Media)
#player.set_fullscreen(False)
self.player.play()
self.player.set_fullscreen(True)
master.attributes('-topmost', 'true') #force the window to be infront
time.sleep(5) #give player time to load before spawning the control buttons
master.bind('<Key>', partial(self.press_button) )
master.mainloop()
self.timed_opacity_thread = threading.Thread(target=self.timed_opacity) #make a thread which manage when the opacity of the buttons will turn on and off
self.timed_opacity_thread.start()
def press_button(self, event): #tells the program what to do if a button is pressed
print("pressed button in video screen")
if show_button == True: #if the opacity is set to be visable simple extend the time
global button_timer
button_timer = time.perf_counter()
else: # if the opacity is off turn it back on and place it into a thread to that other tasks can be performed at the same time.
self.timed_opacity_thread = threading.Thread(target=self.timed_opacity)
self.timed_opacity_thread.start()
global videoscreen_button_num
old_button_num = videoscreen_button_num
print("button pressed", event.keycode)
if event.keycode == 40 : #up button
if videoscreen_button_num == 2:
videoscreen_button_num = 0
else:
videoscreen_button_num = videoscreen_button_num + 1
if event.keycode == 38 : #down
if videoscreen_button_num == 0 :
videoscreen_button_num = 2
else:
videoscreen_button_num = videoscreen_button_num - 1
if event.keycode == 37: #right
if videoscreen_button_num == 2:
videoscreen_button_num = 0
else:
videoscreen_button_num = videoscreen_button_num + 1
if event.keycode == 39 : #left
if videoscreen_button_num == 0 :
videoscreen_button_num = 2
else:
videoscreen_button_num = videoscreen_button_num - 1
if event.keycode == 13: #enter
print("pressed enter")
self.video_button_ids[videoscreen_button_num].invoke()
print("old button = ", old_button_num)
print ("new button = ", videoscreen_button_num)
print ("old object = ", self.video_button_ids[old_button_num])
print ("new object = ", self.video_button_ids[videoscreen_button_num])
unselected_colour = "SteelBlue1"
selected_colour = "RoyalBlue1"
self.video_button_ids[old_button_num].config(background = unselected_colour)
self.video_button_ids[videoscreen_button_num].config(background = selected_colour)
print("")
def timed_opacity(self): #make the buttons fade when no user input is detected for a while and then reappear when a user input is detected
self.master.attributes('-alpha', 1)
global button_timer
global show_button
button_timer = time.perf_counter()
show_button = True
while time.perf_counter() - button_timer < 10:
pass
self.master.attributes('-alpha', .5)
show_button = False
def close_windows(self):
self.player.stop()
global show_button
self.master.destroy() #get rid of window, app still runs, not sure how to kill app
def refresh_video(self):
print("refresh video funtion")
self.player.Refresh()
def main():
root = tk.Tk()
app = video_window(root, 'rtsp://192.168.8.20/4') #the location of the video you wish to play
root.mainloop()
if __name__ == '__main__':
main()
希望这可以帮助别人