1

Python は初めてで、cairo と wxpython を使用して簡単なプログラムを作成しようとしています。私は gtk と C で cairo を使用することに慣れていますが、混乱しています。

次のコードを使用して、単純な UI を作成しました。

import wx

class Frame(wx.Frame):

    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs) 
        self.InitUI()

    def InitUI(self):
        #----------------------------------------------------
        # Build menu bar and submenus   
        menubar = wx.MenuBar()
        # file menu containing quit menu item
        fileMenu = wx.Menu() 
        quit_item = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+W')
        fileMenu.AppendItem(quit_item)
        self.Bind(wx.EVT_MENU, self.OnQuit, quit_item)
        menubar.Append(fileMenu, '&File')      

        # help menu containing about menu item
        helpMenu = wx.Menu() 
        about_item = wx.MenuItem(helpMenu, wx.ID_ABOUT, '&About\tCtrl+A')
        helpMenu.AppendItem(about_item)
        self.Bind(wx.EVT_MENU, self.OnAboutBox, about_item)
        menubar.Append(helpMenu, '&Help')     

        self.SetMenuBar(menubar)

        #----------------------------------------------------
        # Build window layout

        panel = wx.Panel(self)        
        #panel.SetBackgroundColour('yellow')
        vbox = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox)        

        midPan = wx.Panel(panel)
        #midPan.SetBackgroundColour('blue')
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
        midPan.SetSizer(hbox)      

        smallPan = wx.Panel(panel)
        #smallPan.SetBackgroundColour('red')
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        vbox.Add(smallPan, 0, wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT|wx.BOTTOM, 12)
        smallPan.SetSizer(hbox2)   

        #----------------------------------------------------
        # Place buttons in correct box corresponding with panel

        close_button = wx.Button(smallPan, wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.OnQuit, close_button)

        hbox2.Add(close_button)
        #----------------------------------------------------
        # Set window properties

        self.SetSize((1600, 1200))
        self.SetTitle('PROGRAM NAME')
        self.Centre()

    def OnQuit(self, e):
        self.Close()

def main():
    ex = wx.App()
    f = Frame(None)
    f.Show(True)  
    ex.MainLoop()  

if __name__ == '__main__':
    main()

midPanというパネルに描画できるようにしたいです。OnDraw 関数を追加してシグナル ハンドラをリンクするにはどうすればよいですか?

大変助かります。

4

2 に答える 2

1

手続き型プログラミングに慣れている場合、混乱するのは自然なことです。Python は OOP 言語であり、OOP 言語でのコーディングはまったく異なります。提供された例をクリーンアップして更新しました。描画領域として使用されるパネルは、3 つの色付きの長方形をペイントします。メソッドの実装を提供していないOnAboutBox()ため、その行をコメントアウトしました。

#!/usr/bin/python

import wx
import wx.lib.wxcairo
import cairo

class DrawingArea(wx.Panel):
    
    def __init__ (self , *args , **kw):
        super(DrawingArea , self).__init__ (*args , **kw)
        
        self.SetDoubleBuffered(True)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        
    def OnPaint(self, e):
        
        dc = wx.PaintDC(self)
        cr = wx.lib.wxcairo.ContextFromDC(dc)
        self.DoDrawing(cr)     
        
    def DoDrawing(self, cr):
        
        cr.set_source_rgb (0.2 , 0.23 , 0.9)
        cr.rectangle(10 , 15, 90, 60)
        cr.fill()
        
        cr.set_source_rgb(0.9 , 0.1 , 0.1)
        cr.rectangle(130 , 15, 90, 60)
        cr.fill()
        
        cr.set_source_rgb(0.4 , 0.9 , 0.4)
        cr.rectangle(250 , 15, 90, 60)       
        cr.fill()     


class Frame(wx.Frame):

    def __init__(self, *args, **kwargs):
        super(Frame, self).__init__(*args, **kwargs) 
        
        self.InitUI()

    def InitUI(self):
        #----------------------------------------------------
        # Build menu bar and submenus   
        
        menubar = wx.MenuBar()
        # file menu containing quit menu item
        fileMenu = wx.Menu() 
        quit_item = wx.MenuItem(fileMenu, wx.ID_EXIT, '&Quit\tCtrl+W')
        fileMenu.AppendItem(quit_item)
        self.Bind(wx.EVT_MENU, self.OnQuit, quit_item)
        menubar.Append(fileMenu, '&File')      

        # help menu containing about menu item
        helpMenu = wx.Menu() 
        about_item = wx.MenuItem(helpMenu, wx.ID_ABOUT, '&About\tCtrl+A')
        helpMenu.AppendItem(about_item)
        #~ self.Bind(wx.EVT_MENU, self.OnAboutBox, about_item)
        menubar.Append(helpMenu, '&Help')     

        self.SetMenuBar(menubar)

        #----------------------------------------------------
        # Build window layout

        panel = wx.Panel(self)        
        vbox = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox)        

        midPan = DrawingArea(panel)
        vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
    

        smallPan = wx.Panel(panel)
        hbox2 = wx.BoxSizer(wx.HORIZONTAL)
        vbox.Add(smallPan, 1, wx.EXPAND|wx.ALL, 12)
        smallPan.SetSizer(hbox2)   

        #----------------------------------------------------
        # Place buttons in correct box corresponding with panel

        close_button = wx.Button(smallPan, wx.ID_CLOSE)
        self.Bind(wx.EVT_BUTTON, self.OnQuit, close_button)

        hbox2.Add(close_button)
        
        #----------------------------------------------------
        # Set window properties

        #~ self.SetSize((1600, 1200))
        self.SetSize((400, 250))
        #~ self.Maximize()
        self.SetTitle('PROGRAM NAME')
        self.Centre()

    def OnQuit(self, e):
        self.Close()

def main():
    ex = wx.App()
    f = Frame(None)
    f.Show(True)  
    ex.MainLoop()  

if __name__ == '__main__':
    main()

描画を行うために、描画領域として機能するカスタム クラスを作成します。wx.Panelウィジェットから継承します。

class DrawingArea(wx.Panel):
    
    def __init__ (self , *args , **kw):
        super(DrawingArea , self).__init__ (*args , **kw)
        
        self.SetDoubleBuffered(True)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
...

これは、描画に使用されるカスタム クラスです。コンストラクターで、ペイント イベントをOnPaint()メソッドにバインドします。

def OnPaint(self, e):
        
    dc = wx.PaintDC(self)
    cr = wx.lib.wxcairo.ContextFromDC(dc)
    self.DoDrawing(cr)  

メソッド内OnPaint()で cairo 描画コンテキストを作成し、実際の描画コードをDoDrawing() メソッドに委譲します。

midPan = DrawingArea(panel)
vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)

作図領域が作成され、垂直ボックスに追加されます。

#~ self.SetSize((1600, 1200))
self.SetSize((400, 250))
#~ self.Maximize()

最後の注意: ウィンドウを最大化して表示する場合は、Maximize() メソッドを呼び出します。パソコンの画面にはさまざまなサイズがあります。

Linux でのスクリーンショットの例

于 2014-05-16T13:37:00.780 に答える
0

非常に単純な描画の例で説明したように、wx.EVT_PAINT を使用します。

MidPan に OnPaint バインディングを追加します。

    # (...)
    midPan = wx.Panel(panel)
    #midPan.SetBackgroundColour('blue')
    hbox = wx.BoxSizer(wx.HORIZONTAL)
    vbox.Add(midPan, 1, wx.EXPAND | wx.ALL, 12)
    midPan.SetSizer(hbox)
    # binding here:
    midPan.Bind(wx.EVT_PAINT, self.OnPaint)
    # (...) rest of code

OnPaint コードを定義します。

   # (...)
   def OnQuit(self, e):
      self.Close()

   # your OnPaint():
   def OnPaint(self,event):
      dc = wx.PaintDC(event.GetEventObject())
      dc.Clear()
      # set up your pen
      dc.SetPen(wx.Pen("BLACK", 4))
      # draw whatever you like
      dc.DrawLine(0, 0, 50, 50)

   # (...) rest of code
于 2014-05-14T21:23:36.003 に答える