主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

IronPython: WPFで異なるスレッド上にあるGUI間での通信

                
 以前にバックグラウンドで動作するスレッドにGUI更新をさせる方法を書いた。デリゲートの宣言方法がわからない場合はそちらの記事から。
http://elicon.blog57.fc2.com/blog-entry-172.html

 マルチウィンドウをシングルスレッド上で動作させる方法も書いた。
http://elicon.blog57.fc2.com/blog-entry-182.html

 今回はマルチウィンドウをそれぞれのスレッド上で動かすことを考えてみる。それぞれのスレッド上で動かすメリットは、ウィンドウごとに異なる処理を割り振れることだ。
 異なるウィンドウ上にあるGUIパーツ間で通信を行いたい。やってみよう。ウィンドウが異なるスレッド上で動いているので、Dispatcherを使ってGUIを更新する必要がある。
 以前にシングルスレッドで2つのウィンドウを動かしたとき(参照)と同様に、テキストボックスの中身をミラーリングするスクリプトを書いてみる。重要な点は、異なるスレッド上にあるGUIには同時にアクセスできないということ。まずイベント発生によって呼び出されたスレッド上にあるGUIからデータを受けとり、次にDispathcerでデータを反映させたいGUIのあるスレッドに処理を移す必要がある。

Window1.py
import wpf, clr

import System
from System import Windows, Threading
from System.Windows import Window
from System import Action

from Window2 import Window2

class Window1 (Window):
def __init__(self):
wpf.LoadComponent(self, 'Window1.xaml')
self.Show()
self.tBlock = self.FindName('tBlock')
thread = Threading.Thread(System.Threading.ThreadStart(self.RunSubThread))
thread.SetApartmentState(System.Threading.ApartmentState.STA)
thread.IsBackground = True #set True: Stop thread when Window1 closes
thread.Start()

def RunSubThread(self):
subThread = Window2()
subThread.Closed += self.CloseWindow2
subThread.tBox.TextChanged += self.MirrorText
self.subThread = subThread
Windows.Threading.Dispatcher.Run()

def CloseWindow2(self, target, e):
print "Window2 closed"

def MirrorText(self, target, e):
# can access "thread of Window2" and can't access "thread of Window1"
string = target.Text
print self.subThread.tBox.Text
self.tBlock.Dispatcher.Invoke(Action[str](self.MirrorTextInvoke), string)

def MirrorTextInvoke(self, string):
# can't access "thread of Window2" and can access "thread of Window1"
self.tBlock.Text = string


Window1.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1"
Height="300"
Width="300">
<Grid Name="grid">
<TextBlock Name="tBlock">Hello Absurd World!</TextBlock>
</Grid>
</Window>


Window2.py
import wpf

import System
from System.Windows import Window

class Window2 (Window):
def __init__(self):
wpf.LoadComponent(self, 'Window2.xaml')
self.tBox = self.FindName('tBox')
self.Show()


Window2.xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window2"
Height="300"
Width="300">
<Grid Name="grid">
<TextBox Name="tBox">Hello Absurd World!</TextBox>
</Grid>
</Window>


Application.py
import wpf, sys
sys.path.append('Lib')

from System.Windows import Application
from Window1 import Window1

window = Window1()
app = Application()
app.Run(window)
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。