2017-02-17 204 views
2

我是wxpython的新手。我無法重疊面板。一般來說,使用兩個或多個面板很容易,但如果其中一個面板的MediaCtrl容器在整個顯示屏幕上播放視頻,則任何其他面板都不可見。我嘗試了panel.Raise()方法,但仍然無法正常工作。 我期待的所有內容都是通過videoPlayer面板將靜態文本與虛擬面板重疊。在下面的代碼中,綠色框位於MediaCtrl控制器的下方。我必須以某種方式將視頻面板上方的面板。我經歷了很多問題,但我所能得到的只是使用.Raise(),而不是在我的情況下工作。WXPython視頻MediaCtrl自定義按鈕

import wx 
import wx.media 
import os 


######################################################################## 
class MyPanel(wx.Panel): 
    """""" 

    # ---------------------------------------------------------------------- 
    def __init__(self, parent): 
     """""" 
     wx.Panel.__init__(self, parent) 
     self.parent_size = parent.GetClientSize() 
     self.init_view() 

    def init_view(self): 

     #self.SetDimensions(0, 0, wx.GetDisplaySize().width, wx.GetDisplaySize().height) 
     self.SetDimensions(0, 0, 50,50) 
     self.text_view = wx.StaticText(self, size=(1020, 40), pos=(10, 10), label="Some Label") 
     self.mc = wx.media.MediaCtrl(self) 

     # from wx.animate import AnimationCtrl 
     # self.text_view.write("ABDS") 
     self.settings_btn = wx.Button(self, -1, "Settings") 
     self.Bind(wx.EVT_BUTTON, self.settings_button_clicked, self.settings_btn) 
     self.Bind(wx.EVT_LEFT_UP, self.on_panel_clicked) 
     print(os.path.exists("SampleVideo_1280x720_10mb.mp4")) 
     path = os.path.dirname(os.path.abspath("SampleVideo_1280x720_10mb.mp4")) + "/SampleVideo_1280x720_10mb.mp4" 
     if not self.mc.Load(path): 
      print("unable to load video") 
     else: 
      self.mc.SetInitialSize() 
      self.mc.Play() 


    def on_panel_clicked(self, event): 
     print("panel clicked...") 
     if self.settings_btn.IsShown(): 
      self.settings_btn.Hide() 
     else: 
      self.settings_btn.Show() 

    def settings_button_clicked(self, event): 
     print("Settings Btn Clicked...") 


class BannerPanel(wx.Panel): 
    def __init__(self, parent): 
     wx.Panel.__init__(self, parent) 
     self.SetBackgroundColour("green") 
     self.SetDimensions(0, 0, 100, 100) 
     self.Raise() 
     #self.ToggleWindowStyle(wx.STAY_ON_TOP) 


######################################################################## 
class MyFrame(wx.Frame): 
    """""" 

    # ---------------------------------------------------------------------- 
    def __init__(self): 
     """""" 
     # wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN 
     wx.Frame.__init__(self, None, title="Test Maximize", size=wx.Size(1100, 700), style=wx.CLIP_CHILDREN) 
     self.videoPlayerPanel = MyPanel(self) 
     self.bannerPanel = BannerPanel(self) 
     self.Show() 
     # self.videoPlayerPanel.mc.Lower() 
     self.bannerPanel.Raise() 
     # print(self.GetClientSize()) 
     # self.Maximize(True) 
     # self.initGUI() 


if __name__ == "__main__": 
    app = wx.App(False) 
    frame = MyFrame() 
    # frame.ShowFullScreen(True) 
    app.MainLoop() 

回答

1

嘗試添加一個sizer,然後將面板添加到sizer中。這應該確保面板可以被操縱並保存在正確的位置。它很好看的https://wiki.wxpython.org/BoxSizerFromTheGroundUp 你可以做的是編輯:

class MyFrame(wx.Frame): 
"""""" 

# ---------------------------------------------------------------------- 
def __init__(self): 
    """""" 
    # wx.MINIMIZE_BOX | wx.MAXIMIZE_BOX | wx.RESIZE_BORDER | wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX | wx.CLIP_CHILDREN 
    wx.Frame.__init__(self, None, title="Test Maximize",  size=wx.Size(1100, 700), style=wx.CLIP_CHILDREN) 
    self.videoPlayerPanel = MyPanel(self) 
    self.bannerPanel = BannerPanel(self) 

    self.vsizer = wx.BoxSizer(wx.VERTICAL) 
    self.vsizer.Add(self.videoPlayerPanel, 0) 
    self.videoPlayerPanel.SetSizer(self.vsizer) 
    self.videoPlayerPanel.Show() 

    self.bsizer = wx.BoxSizer(wx.VERTICAL) 
    self.bsizer.Add(self.bannerPanel, 0) 
    self.bannerPanel.SetSizer(self.bsizer) 
    self.bannerPanel.Raise() 
    self.bannerPanel.Show() 

有了一些調整,你可以設置面板尺寸和它們在框架上的位置,看看該鏈接,一個真正的好說明。

+0

嗨,尼克,謝謝你的回覆。但是在垂直佈局中使用BoxSizer時,兩個面板都以垂直佈局進入,而我試圖將bannerPanel放在videoPlayerPanel上方。 – rohitranjan

+0

我編輯了我的回覆,我認爲他們可能需要分開調整大小,然後再提高第二個大小。 –

+0

嗨,尼克,感謝您對此進行調查。我試着用上面的代碼,理想情況下你的代碼應該與面板一起使用像statictext等小部件面板,但我認爲這個問題必須做一些特定的wx.media.MediaCtrl,我用於視頻播放器,不知何故它不允許任何其他提出的觀點/面板超過它。 – rohitranjan

1

@rohitranjan,這個答案太長了評論,我遇到了mediactrl的麻煩。我唯一能想到的其他方法是創建第二個透明窗口(框架),只顯示文本。這就是我在這裏嘗試的,但確保窗口在正確的位置可能證明是棘手的。我的另一個想法是 - 它是一個靜態視頻,即沒有流式傳輸?您可以使用不同的進程(如openCV)首先覆蓋文本。我不記得太多,但它是這樣的:import cv2cv2.puText(frame, text, position)。您也可能需要cv2.VideoWriter()cv2.VideoCapture()。這就是我接下來要研究的內容,在wx導入和播放視頻之前疊加文本。公開搜索opencv,視頻文本疊加應該是有用的。

+0

嗨,尼克,感謝您的建議,我確實嘗試繪製一個文本,如https://wiki.wxpython.org/VerySimpleDrawing,但即使這是不可見的視頻。我也嘗試過提高textview並降低視頻播放器視圖,但仍然以某種方式視頻播放器視圖隱藏所有其他小部件。我找不到連接OpenCV和wxpython框架/面板的文章。如果你能指導我到一個有這樣的網站,這將幫助我嘗試它。我想必須更深入地研究mediactrl才能找到答案。 – rohitranjan

1

好的,我在這裏工作,我先給視頻添加文本,然後使用wx播放視頻。所以基本上,「預編輯」視頻。它的初始速度並不快,取決於你的視頻尺寸,但它使得這個過程變得更容易,因爲你只是在播放一個視頻。我使用MoviePy,它導入視頻,在頂部添加文本,然後將其導出到同一個目錄。我在上面

from moviepy.editor import * 

clip = VideoFileClip("your_video.mp4") 
txt_overlay = TextClip("test text", fontsize=50, color='white') 
clip.write_videofile("output.mp4", codec='mpeg4') 
從這裏

然後將此添加到您的原代碼,你可以在一個窗口中使用「output.mp4」運行代碼的其餘部分。它可能並不是你所需要的,因爲它最初只涉及一小段時間處理文件,但如果它不是流,那麼它工作得非常好。我不確定你正在運行什麼系統,但是這裏是到MoviePy模塊的鏈接。 https://zulko.github.io/moviepy/crash_course/crash_course.html

+0

嗨,感謝您將我介紹給MoviePy。它的確按照你說的方式工作。但問題在於,我必須在視頻面板上方放置很多其他小部件,而且我的案例中的文本會隨着其他觸發器而不斷變化。所以你看我不得不把面板放在視頻面板上方。 – rohitranjan