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

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)
スポンサーサイト



プロフィール

h

Author:h

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

検索フォーム
Amazon