2017-02-17 202 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