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

スポンサーサイト

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

IronPython: WPFでフォトビューワを作ってみる

                
 IronPythonでWPFを使って、フォトビューワを作ってみる。写真の表示切り換えは瞬間的に行われるのではなく、古い写真がフェードアウトしてから新しい写真がフェードインするようにしたい。そういう場合に使うのがStotyboardDoubleAnimation

 このアニメーション効果は、XAMLに表記することで簡単に使える。これは各Control要素のイベントに結びつけやすい。下記のXAMLはマウスのオン、オフによっておこるアニメーションを記述してある。
<DockPanel.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="DockPanel.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="control"
Storyboard.TargetProperty="Opacity"
To="0.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="DockPanel.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="control"
Storyboard.TargetProperty="Opacity"
To="1.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DockPanel.Triggers>


一方で、スクリプト内で書くこともできる。こうしておくとスクリプトから呼び出しやすい。
ターゲットのフェードアウト完了から、フェードインを呼びたかったので、Completedイベントにメソッドへの参照を渡している。SomeMethod()に写真の入れ替えを記述しておけば、フェードアウト中に写真の入れ替えを行ってくれる。
        self.fadeOut = DoubleAnimation()
self.fadeOut.To = 0.0
self.fadeOut.Duration = Duration(TimeSpan.FromSeconds(0.3))
self.fadeoutStory = Storyboard()
self.fadeoutStory.Children.Add(self.fadeOut)
self.fadeoutStory.SetTargetName(self.fadeOut, self.background.Name)
self.fadeoutStory.SetTargetProperty(self.fadeOut, PropertyPath(self.background.OpacityProperty))

self.fadeIn = DoubleAnimation()
self.fadeIn.To = 1.0
self.fadeIn.Duration = Duration(TimeSpan.FromSeconds(0.3))
self.fadeinStory = Storyboard()
self.fadeinStory.Children.Add(self.fadeIn)
self.fadeinStory.SetTargetName(self.fadeIn, self.background.Name)
self.fadeinStory.SetTargetProperty(self.fadeIn, PropertyPath(self.background.OpacityProperty))

self.fadeoutStory.Completed += self.FadeoutCompleted

def FadeoutCompleted(self, target, e):
SomeMethod()
self.fadeinStory.Begin(self.background)



下記のスクリプトの実行にはMicrosoft.Windows.Shell.dllが必要。
http://msdn.microsoft.com/ja-jp/library/ff799534(v=vs.100).aspx

Window1.py
import sys, clr, wpf

clr.AddReference('System.Windows.Forms')
clr.AddReference('System.Drawing')
clr.AddReference('Microsoft.Windows.Shell')

import System
from System import Windows, Threading, Uri, TimeSpan, Environment
from System.Windows import Window, Controls, Thickness, Duration, PropertyPath
from System.Windows.Media import Imaging, ImageBrush, Brushes
from System.Windows.Media.Animation import DoubleAnimation, Timeline, Storyboard
from System import Action
from System.IO import Directory, DirectoryInfo, Path
import System.Windows.Forms
import System.Drawing

EXT = ["*.jpg", "*.jpeg", "*.png", "*.gif",]

class Window1 (Window):
def __init__(self):
wpf.LoadComponent(self, 'Window1.xaml')
iconUri = System.Uri("icon.ico", System.UriKind.RelativeOrAbsolute)
self.Icon = System.Windows.Media.Imaging.BitmapFrame.Create(iconUri)

self.myGrid = self.FindName('myGrid')
self.windowBorder = self.FindName('windowBorder')
self.ApplyTemplate() #important to get VisualBrush in ControlTemplate
self.imageBrush = self.Template.FindName("imageBrush", self)
self.background = self.Template.FindName('background', self)
self.control = self.FindName('control')
self.playButton = self.FindName('playButton')
self.Show()

self.GetPictures()

self.Height = 600

self.fadeOut = DoubleAnimation()
self.fadeOut.To = 0.0
self.fadeOut.Duration = Duration(TimeSpan.FromSeconds(0.3))
self.fadeoutStory = Storyboard()
self.fadeoutStory.Children.Add(self.fadeOut)
self.fadeoutStory.SetTargetName(self.fadeOut, self.background.Name)
self.fadeoutStory.SetTargetProperty(self.fadeOut, PropertyPath(self.background.OpacityProperty))

self.fadeIn = DoubleAnimation()
self.fadeIn.To = 1.0
self.fadeIn.Duration = Duration(TimeSpan.FromSeconds(0.3))
self.fadeinStory = Storyboard()
self.fadeinStory.Children.Add(self.fadeIn)
self.fadeinStory.SetTargetName(self.fadeIn, self.background.Name)
self.fadeinStory.SetTargetProperty(self.fadeIn, PropertyPath(self.background.OpacityProperty))
self.fadeoutStory.Completed += self.FadeoutCompleted

def FadeoutCompleted(self, target, e):
self.imageBrush.ImageSource = Imaging.BitmapImage(Uri(self.filename))
self.fadeinStory.Begin(self.background)

def GetPictures(self):
#path = Path.GetDirectoryName(filename)
path = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)
pics = []
for ext in EXT:
pics += DirectoryInfo(path).GetFiles(ext, System.IO.SearchOption.AllDirectories)
self.pics = [pic.FullName for pic in pics]
self.imageBrush.ImageSource = Imaging.BitmapImage(Uri(self.pics[0]))
self.filename = self.pics[0]

def forward(self, target, e):
self.fadeoutStory.Begin(self.background)
pointer = self.pics.index(self.filename)
if pointer < len(self.pics) - 1:
self.filename = self.pics[pointer + 1]
else:
self.filename = self.pics[0]


def rewind(self, target, e):
self.fadeoutStory.Begin(self.background)
pointer = self.pics.index(self.filename)
if pointer != 0:
self.filename = self.pics[pointer - 1]
else:
self.filename = self.pics[len(self.pics) - 1]


def close_window(self, target, e):
self.Close()

def state_change(self, target, e):
state = self.WindowState
if state == System.Windows.WindowState.Normal:
self.WindowState = System.Windows.WindowState.Maximized
elif state == System.Windows.WindowState.Maximized:
self.WindowState = System.Windows.WindowState.Normal

def minimize_window(self, target, e):
self.WindowState = System.Windows.WindowState.Minimized

def move(self, target, e):
self.DragMove()



def switch_fit(self, target, e):
state = self.imageBrush.Stretch
if state == System.Windows.Media.Stretch.Uniform:
self.imageBrush.Stretch = System.Windows.Media.Stretch.UniformToFill
else:
self.imageBrush.Stretch = System.Windows.Media.Stretch.Uniform

def top_mode(self, target, e):
state = self.Topmost
print state
if state == True:
self.Topmost = False
else:
self.Topmost = True


Window1.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title=""
FontFamily="Meiryo UI"
Width="800"
MinWidth="320"
Height="600"
MinHeight="200"
Name="window"
Background="Aqua"
WindowStartupLocation="CenterScreen"
WindowStyle="SingleBorderWindow"
ResizeMode="CanResizeWithGrip" >
<Window.CommandBindings>
<CommandBinding Command="{x:Static shell:SystemCommands.CloseWindowCommand}"
Executed="close_window"/>
<CommandBinding Command="{x:Static shell:SystemCommands.MaximizeWindowCommand}"
Executed="state_change"/>
<CommandBinding Command="{x:Static shell:SystemCommands.MinimizeWindowCommand}"
Executed="minimize_window"/>
</Window.CommandBindings>
<Window.Resources>
<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}" x:Name="buttonStyle1">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border BorderBrush="Gray" BorderThickness="1" Margin="0,0,0,0" >
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ButtonStyle2" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border"
BorderThickness="1"
Padding="4,2"
BorderBrush="DarkGray"
CornerRadius="3"
Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.Style>
<Style TargetType="Window">
<Setter Property="shell:WindowChrome.WindowChrome">
<Setter.Value>
<shell:WindowChrome GlassFrameThickness="1" />
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Window">
<Grid>
<Border Name="background" BorderThickness="0.8" BorderBrush="Aqua">
<Border.Background>
<ImageBrush
x:Name="imageBrush"
Stretch="Uniform" />
</Border.Background>
<ContentPresenter Margin="0" Content="{TemplateBinding Content}"/>
</Border>

<!-- Title プロパティを表示する -->
<TextBlock HorizontalAlignment="Left" VerticalAlignment="Top" Margin="34,8,0,0" Foreground="White"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title}" />

<!-- 最小化、最大化、閉じるボタン -->
<StackPanel Name="frameButtons" shell:WindowChrome.IsHitTestVisibleInChrome="True" Orientation="Horizontal" Margin="0,6,6,0" HorizontalAlignment="Right" VerticalAlignment="Top" Background="Transparent" Opacity="0">
<StackPanel.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="StackPanel.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="frameButtons"
Storyboard.TargetProperty="Opacity"
To="0.0" Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="StackPanel.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="frameButtons"
Storyboard.TargetProperty="Opacity"
To="1.0" Duration="0:0:0.5"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</StackPanel.Triggers>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Style="{StaticResource ButtonStyle2}"
Height="24" Margin="30,10,0,0" Width="28"
Background="Black"
BorderThickness="0"
Click="switch_fit" >
<TextBlock Foreground="White">&gt; &lt;</TextBlock>
</Button>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Style="{StaticResource ButtonStyle2}"
Height="24" Margin="30,10,0,0" Width="28"
Background="Black"
BorderThickness="0"
Command="{x:Static shell:SystemCommands.MinimizeWindowCommand}"
CommandParameter="{Binding ElementName=window}">
<TextBlock Foreground="White">_</TextBlock>
</Button>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Style="{StaticResource ButtonStyle2}"
Height="24" Margin="30,10,0,0" Width="28"
Background="Black"
Command="{x:Static shell:SystemCommands.MaximizeWindowCommand}"
CommandParameter="{Binding ElementName=window}">
<TextBlock Foreground="White" FontFamily="Marlett">1</TextBlock>
</Button>
<Button shell:WindowChrome.IsHitTestVisibleInChrome="True"
Style="{StaticResource ButtonStyle2}"
Height="24" Margin="30,10,20,0" Width="28"
Background="Black"
Command="{x:Static shell:SystemCommands.CloseWindowCommand}"
CommandParameter="{Binding ElementName=window}">
<TextBlock Foreground="White" FontFamily="Marlett">r</TextBlock>
</Button>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Style>
<DockPanel
x:Name="myGrid"
Width="Auto"
Height="Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Transparent"
MouseDown="move">
<DockPanel.Triggers>
<!-- Animates the rectangle's opacity. -->
<EventTrigger RoutedEvent="DockPanel.MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="control"
Storyboard.TargetProperty="Opacity"
To="0.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="DockPanel.MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="control"
Storyboard.TargetProperty="Opacity"
To="1.0" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DockPanel.Triggers>
<WrapPanel
Name="control"
Width="Auto"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
DockPanel.Dock="Bottom" >
<Button
HorizontalAlignment="Right"
Width="75"
Height="35"
Click="rewind"
Margin="10,0,10,10" Background="White" FontWeight="Bold" >
<Image Source="rewind.png" />
</Button>
<Button
Name="forwardButton"
HorizontalAlignment="Right"
Width="75"
Height="35"
Margin="10,0,10,10" Background="White" FontWeight="Bold"
Click="forward" >
<Image Source="forward.png" />
</Button>
<ResizeGrip
HorizontalAlignment="Right"
VerticalAlignment="Bottom" />
</WrapPanel>
</DockPanel>
</Window>


Application.py
import wpf, clr

from System.Windows import Application
from Window1 import Window1

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

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

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

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