5

私はwinxpとwxpython(wxpython 3.1、python 2.6)を使用して、TextCtrlからStaticTextを含むScrollablePanelにテキストをコピーするGUIプログラムを作成しています。これはすべて正常に機能しますが、スクロールされた部分は正しく機能しません。リアルタイムで更新されないようです。ウィンドウを最大化して再び最大化すると、スクロールバーが更新されます。ただし、TextCtrlをもう一度入力し始めると(イベントを使用してScrollablePanel内のStaticTextにテキストを追加する)、再度最小化しない限り、パネルのスクロールバーは更新されません。

だから問題は、どうすればScrolledPanelをリアルタイムで更新できるかということです。TextCtrlでテキストが変更されるのを待つイベント設定があります。ここで、更新を行う必要があると思います。Update、Refresh、Layoutを試しましたが、あまり効果がなかったようです。より大きな問題は、ウィンドウを最小化して再度最大化すると、更新、更新、およびレイアウトでは何ができないのかということです。これを手伝ってくれてありがとう。申し訳ありませんが、機密情報としてコードを投稿できません。あなたが私に与えることができるどんな助けでもありがたいです。私は通常、検索することで自分で問題を見つけることができますが、この種のことに関するドキュメントは見つかりませんでした。初めてですが、たくさんのご回答をいただきました。再度、感謝します!:)

追加した:

import wx
import wx.lib.inspection
from wx.lib.scrolledpanel import ScrolledPanel

class MyFrame( wx.Frame ):

    # TODO: add all class variables here for convention
    tin         = None

    hsizer      = None

    def __init__( self, parent, ID, title ):
        wx.Frame.__init__( self, parent, ID, title,
                     wx.DefaultPosition, wx.Size( 200, 150 ) )

        self.InitWidgets()
        self.InitBindings()
        self.InitFinish()


    def InitWidgets( self ):
        self.hsizer = wx.BoxSizer( wx.HORIZONTAL )

        # Add the TextCtrl
        vsizer = wx.BoxSizer( wx.VERTICAL )
        self.tin = wx.TextCtrl( self, style=wx.TE_MULTILINE )
        vsizer.Add( self.tin, 1, wx.EXPAND  )
        self.hsizer.Add( vsizer, 3, wx.TOP|wx.LEFT|wx.BOTTOM|wx.EXPAND, border=20 )

        # Add ScrolledPanel widget
        self.hsizer.Add( wx.Size( 200, -1 ), 1 )
        vsizer2 = wx.BoxSizer( wx.VERTICAL )
        self.test_panel = ScrolledPanel( self )
        self.test_panel.SetupScrolling()

        # Setup static text ( label ) tvs is the 
        # vertical sizer inside the panel
        self.tvs = wx.BoxSizer( wx.VERTICAL )
        self.tin2 = wx.StaticText( self.test_panel )
        self.tvs.Add( self.tin2, 0, wx.EXPAND )
        vsizer2.Add( self.test_panel, 1, wx.EXPAND  )
        self.hsizer.Add( vsizer2, 3, wx.TOP|wx.LEFT|wx.BOTTOM|wx.EXPAND, border=20 )

        # Add Spacer
        self.hsizer.Add( wx.Size( 500, -1 ), 1 ) 

    def InitBindings( self ):
        self.tin.Bind( wx.EVT_TEXT, self.TextChange ) 

    def InitFinish( self ):

        # Setup sizers and frame
        self.SetAutoLayout( True )
        self.test_panel.SetAutoLayout( True )
        self.test_panel.SetSizer( self.tvs )
        self.SetSizer( self.hsizer )
        self.Layout()
        self.Update()
        self.Maximize()

    def TextChange( self, event ):

        #self.CopyValues()
        self.tin2.Label = self.tin.GetValue()
        self.Layout()
        self.Update()
        self.test_panel.Refresh()
        self.test_panel.Update()
        print self.tin.GetValue().split( "\n" )


class MyApp( wx.App ):

    fr = None

    def OnInit( self ):
        self.fr = MyFrame( None, -1, "TitleX" )
        self.fr.Show( True )
        self.SetTopWindow( self.fr )
        return True

app = MyApp( 0 )
app.MainLoop()

def main():

    win = 1
if ( __name__ == "__main__" ):
    main()    

一般的に、これはプログラムの目的をあまり与えずに起こっていることです。パネルのサイズが塗りつぶしの領域よりも大きくなるように仮想サイズを設定しました。永続的なスクロールバーがあることを期待していますが、そうではありません。

4

1 に答える 1

8

コピーアンドペーストの直後に実行されている可能性のあるものを投稿するとよいでしょう。

とにかく、スクロールパネルを機能させるために必須の次のことを見逃したようです。

  1. スクロールされたパネルにはサイザーが必要です。self.test_panel.SetSizer(self.a_sizer)これは、メソッドを介して実行できます。パネル内の他のすべてのコントロールは、このサイザーに接続する必要があります。

  2. パネルでSetupScrolling()メソッドを呼び出す必要があります。self.test_panel.SetupScrolling()

  3. パネルの自動レイアウトを有効にする必要があります。例:self.test_panel.SetAutoLayout(1)

PS wxPythonコードの例を見たことがありますか?それらのほとんどすべてがそのような素晴らしい方法を持っているので、私は尋ねてい__do_layoutます。このアプローチは、コードをはるかに読みやすくするのに役立ちます。

編集:

パネルに子コントロールのサイズを再計算させ、独自の仮想サイズを更新させるには、TextChangeメソッドにself.test_panel.FitInside()を追加する必要があります。

完全な解決策は次のとおりです。

import wx
from wx.lib.scrolledpanel import ScrolledPanel

class MyFrame( wx.Frame ):
    def __init__( self, parent, ID, title ):
        wx.Frame.__init__( self, parent, ID, title,
                         wx.DefaultPosition, wx.Size( 600, 400 ) )
        #Controls
        self.tin = wx.TextCtrl( self, 
                                size = wx.Size( 600, 400 ),
                                style=wx.TE_MULTILINE )        
        self.test_panel = ScrolledPanel( self, 
                                         size = wx.Size( 600, 400 ) )
        self.test_panel.SetupScrolling()
        self.tin2 = wx.StaticText( self.test_panel )

        #Layout
        #-- Scrolled Window
        self.panel_sizer = wx.BoxSizer( wx.HORIZONTAL )
        self.panel_sizer.Add( self.tin2, 0, wx.EXPAND )
        self.test_panel.SetSizer( self.panel_sizer )
        self.panel_sizer.Fit(self.test_panel)
        #-- Main Frame
        self.inner_sizer = wx.BoxSizer( wx.HORIZONTAL )        
        self.inner_sizer.Add( self.tin, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 50  )
        self.inner_sizer.Add( self.test_panel, 1, wx.LEFT | wx.RIGHT | wx.EXPAND, 50  )

        self.sizer = wx.BoxSizer( wx.VERTICAL )
        self.sizer.Add(self.inner_sizer, 1, wx.ALL | wx.EXPAND, 20)        
        self.SetSizer(self.sizer)
        self.sizer.Fit(self)
        self.sizer.Layout()

        self.test_panel.SetAutoLayout(1)

        #Bind Events
        self.tin.Bind( wx.EVT_TEXT, self.TextChange )

    def TextChange( self, event ):
        self.tin2.SetLabel(self.tin.GetValue())
        self.test_panel.FitInside()


class MyApp( wx.App ):
    def OnInit( self ):
        self.fr = MyFrame( None, -1, "TitleX" )
        self.fr.Show( True )
        self.SetTopWindow( self.fr )
        return True

app = MyApp( 0 )
app.MainLoop()

def main():

    win = 1

if ( __name__ == "__main__" ):
    main()    
于 2011-05-06T16:08:25.420 に答える