ブログ

割とコンピュータよりの情報をお届けします。

TakeMe

WPFでTextBox内で上下キーでフォーカスを遷移

WPFでTextBoxにフォーカスが当たっているときに上下キーを押すとフォーカスを遷移できる仕組みを実装していた。

xamlにはTextBoxが複数並べた。
そのTextBoxにはKeyUpのイベントハンドラを設定している。

<TextBox HorizontalAlignment="Left" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" KeyUp="TextBox_KeyUpEvent"/>

コードビハインドでは以下のように設定を追加してみた。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_KeyUpEvent(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down)
            {
                var direction = FocusNavigationDirection.Next;
                (FocusManager.GetFocusedElement(this) as FrameworkElement)?.MoveFocus(new TraversalRequest(direction));
            } else if (e.Key == Key.Up)
            {
                var direction = FocusNavigationDirection.Previous;
                (FocusManager.GetFocusedElement(this) as FrameworkElement)?.MoveFocus(new TraversalRequest(direction));
            }
        }
    }
}

FocusNavigationDirection.Nextとか,FocusNavigationDirection.Previousとかはよいが,?を使った書法は参考ページにあったものだが,珍しい書き方だったので引用してしまった。
もし私がコーディングしたら以下のようになる(かな)

private void TextBox_KeyUpEvent(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Down)
            {
                var direction = FocusNavigationDirection.Next;
                FrameworkElement element = (FrameworkElement)FocusManager.GetFocusedElement(this);
                if (element != null)
                    element.MoveFocus(new TraversalRequest(direction));
            } else if (e.Key == Key.Up)
            {
                var direction = FocusNavigationDirection.Previous;
                FrameworkElement element = (FrameworkElement)FocusManager.GetFocusedElement(this);
                if (element != null)
                    element.MoveFocus(new TraversalRequest(direction));
            }
        }

≫ Read More

2018/10/13 コンピュータ   TakeMe
Tag:WPF

node.js pkgは10.xの最新系に非対応?(一緒に入れているPythonのバージョン問題か?)

node.js pkgをいろいろ試しているとnode-v10.2.xくらいは問題なく動くが,一部のバージョンを入れている環境では失敗していた。

普通はnode-v10.11.0-win-x64でも以下のコマンドで1ファイル化が完了する。

npm install -D pkg
npx pkg serv.js

実行しても環境によっては失敗する。
対策は,nodevars.batに
set "PATH=C:\WinPython-64bit-2.7.13.1Zero\python-2.7.13.amd64;%PATH%"
を追加してみることしか策を持っていない。

Python 3.7が動くようにしてると失敗するだけかもしれない

一応,pkgはPython無しでも動くはずなのに。
 

≫ Read More

2018/10/07 コンピュータ   TakeMe
Tag:Node.js

statnett/vue-plotlyでWebGLをサポートしていないような表示が出る問題

昨日のとある作業で,statnett/vue-plotlyでWebGLをサポートしていないような表示が出る問題が発生して作業が止まってしまった。
"Webgl is not supported by your browser" しかし,WebブラウザはWebGLをサポートはしているのだ。

結局どうすればよいのかということであるが,このパッケージ自体はvue.jsラッパーで大きな内容は書かれていない。
そこで,パッケージ内(node_modules/@statnett/vue-plotly/)Plotly.vueをコピーして手動でimportしてやればよい。
ただし,それではなにも状況が変化しない。
そこで,
import Plotly from 'plotly.js'

import Plotly from 'plotly.js/dist/plotly.min.js'
でおき変える。

これで,この単一ファイルコンポーネントimportすれば使える。

≫ Read More

2018/10/02 コンピュータ   TakeMe

Zipファイルから手動インストールしたNode.jsでnpmアップデート

Zipファイルから手動インストールしたNode.jsでnpmアップデートしようとすると
npm ERR! Refusing to delete C:\node-v10.2.1-win-x64\npm.cmd: is outside C:\node-v10.2.1-win-x64\node_modules\npm and not a link
npm ERR! File exists: C:\node-v10.2.1-win-x64\npm.cmd
npm ERR! Move it away, and try again.
などと出てきてアップデートできない。

何とかならないのかを調べていたら見つかった
最初見逃していたのは「mvn環境」って何,と思っていたから。

参考のページを見ていただくとわかるのだが,実行中のnpmは自分を消せないのだ。
そこでnpm.cmdをnpm2.cmdなどにへんこうしておき,node_modulesの中のnpmの名前を例えばnpm2などに変更しておく。そうすると,npm.cmdが使えなくなるので,直接
node node_modules\npm2\bin\npm-cli.js i -g npm@latest
を実行すればよいというもの。

なるほど。

一応 次の方法でもできないかなー
npm更新用のフォルダで
npm init -y
npm install -D npm
npx npm i -g npm@latest

≫ Read More

2018/09/30 コンピュータ   TakeMe
Tag:Node.js

node.js pkgで1ファイル実行ファイル化

Node.jsでプログラムを配布する際にいちいちNode.jsやパッケージファイルを一緒に提供する必要があるとかなり管理が大変になる。もちろん,JavaScriptのアプリケーションだけがたくさん種類がある場合にはこの限りではないが,一つのアプリを提供するのにファイルがたくさんあるのはあまりやりたくない。

具体的な方法は,pkgを使うということ。
npm install -g pkg
でインストールをする。

これだけで例えばexpressのサーバserv.jsなどを作っていた場合,
pkg serv.js
で実行ファイルが作り始められる。
(npm install -D pkgとした場合にはnpx pkg serv.js)
この時,なにも指定していなければWindows用かLinux用かx86/x64など実行環境を見分けてそれぞれ用に1ファイル化が行われる(ただしx86とx64をまたいで1ファイル化は行われない)。

今回の例

const express = require('express');
const app = express();
app.use(express.static('./'));
app.listen(80, ()=> {
  console.log('Express Server 01');
});

さて,普通がserv.jsにrequireで指定したモジュールもひとまとめにされるのだが,少し癖があって必要なモジュールが抜けることがある。
できれば
npm init -y
でpackage.jsonを用意して,
npm install -D xxxx
でそのアプリケーションの実行に必要なバージョンのモジュールを固めておくとよい(と思う)。
ただし,ほかのアプリケーション用のpackage.jsonのあるフォルダでpkgコマンドを実行すると失敗する可能性がある。

ちなみに上のコマンドnode10-win64ならserv-win.exeができた。
(2018.10.04追加: 一応,上例ではこの操作でserv-linux/serv-macosも出来ている。もし,ターゲットが固定されていれば--target=node10-win-x64を指定してほしい。pure javascriptでないものが混ざるなどserv-linuxやserv-macosが作れない事情があると失敗するらしい)
うまくできた仕組みである。

上の例ではどこが./かは注意。
ショートカットを作って起動する場合には作業フォルダの指令を忘れないでおかないと意図しないフォルダが露出してしまう

 

≫ Read More

2018/09/29 コンピュータ   TakeMe

WPFでTextBoxへの入力に範囲制限を設ける例

WPFでTextBoxに数値をバインドしている場合に入力範囲に制限を設ける例を探していた。

概要としてはEnterキーを押すと入力のチェックが始まり範囲内なら入力が新しい変数値として適用されて,出力側もPropertyChangedイベンドをきっかけに変更される。

MainWindows.xaml

<Window x:Class="WpfApp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="100" Width="300">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">入力</TextBlock>
        <TextBlock Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center">出力</TextBlock>
        <TextBox Grid.Column="1" Grid.Row="0" Width="70"  VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Right" KeyUp="OnKeyUp">
            <TextBox.Text>
                <Binding Path="Value" Mode="TwoWay" UpdateSourceTrigger="LostFocus">
                    <Binding.ValidationRules>
                        <local:DoubleRangeRule MinValue="0" MaxValue="100" />
                    </Binding.ValidationRules>
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBox Text="{Binding Value, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Grid.Row="1" Width="70" Foreground="SkyBlue" Background="AliceBlue" IsReadOnly="True" VerticalAlignment="Center" HorizontalAlignment="Center" TextAlignment="Right"/>
    </Grid>
</Window>

MainWindows.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp1
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private MainWindowViewModel mainWindowViewModel;

        public MainWindow()
        {
            InitializeComponent();

            mainWindowViewModel = new MainWindowViewModel();
            this.DataContext = mainWindowViewModel;
        }

        private void OnKeyUp(object sender, KeyEventArgs e)
        {
            TextBox textBox = (TextBox)sender;
            if (e.Key == Key.Return)
            {
                //System.Windows.Input.Keyboard.ClearFocus();
                textBox.RaiseEvent(new RoutedEventArgs(LostFocusEvent, textBox));
            }
        }
    }
}

 

DoubleRangeRule.cs

(参考ページのintを全部doubleに変更するだけ。)
ちなみに以下は必要
using System.Windows.Controls;
using System.Globalization;

≫ Read More

2018/09/22 コンピュータ   TakeMe

Pythonで複数の画像をまとめる例

Pillowで複数の画像をまとめて一つにする例を作成していた。

今回は一つの画像imから2つの画像を作成したが,im1, im2は別の画像とする。

Image.newで出力の画像を作成しておいて,Image.paste()で貼り付けるImageと貼り付け先を指定してやるだけで画像が一つにまとまる。

from PIL import Image, ImageDraw, ImageFilter

im = Image.open('DSC_0001.JPG')
im1 = im.resize((200, 150))
im2 = im1.filter(ImageFilter.EDGE_ENHANCE)


dst = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))

dst.show()
dst.save('im.png')
#dst.save('im.jpg', 'JPEG', quality=30, optimize=True)

ある処理で,たくさんの画像をまとめたサムネイル化を図っていた。
調べてみたら,ImageDrawのimportはいらない。また,ImageFilterも画像がすでに用意されている場合にはいらない(今回の例だけ)。

≫ Read More

2018/09/22 コンピュータ   TakeMe
Tag:Python

WinPython 2.7は更新が停止?

WinPythonの2.7は2.7.13.1で更新が停止してしまった。
2018年中には,いよいよ,おわりか?
現在CPython自体はバージョンが2.7.15へ進んでいる。

まだまだ,node.jsの一部モジュールがPython 2.7に依存している状況なのだが,なんとかならないのか。
今のところWinPythonの更新が途切れてから1年程度なのでまだ差は大きくないのでnodevars.batは以下のようにしてPATHにWinPythonのフォルダを追加して使っている。

@echo off

rem Ensure this Node.js and npm are first in the PATH
set "PATH=%APPDATA%\npm;%~dp0;%PATH%"

setlocal enabledelayedexpansion
pushd "%~dp0"

rem Figure out the Node.js version.
set print_version=.\node.exe -p -e "process.versions.node + ' (' + process.arch + ')'"
for /F "usebackq delims=" %%v in (`%print_version%`) do set version=%%v

rem Print message.
if exist npm.cmd (
  echo Your environment has been set up for using Node.js !version! and npm.
) else (
  echo Your environment has been set up for using Node.js !version!.
)

popd
endlocal

set "PATH=C:\WinPython-64bit-2.7.13.1Zero\python-2.7.13.amd64;C:\cmake-3.12.0-win32-x86\cmake-3.12.0-win32-x86\bin;%PATH%"
"C:\Program Files (x86)\Microsoft Visual Studio\2017\WDExpress\VC\Auxiliary\Build\vcvars32.bat"

rem If we're in the Node.js directory, change to the user's home dir.
if "%CD%\"=="%~dp0" cd /d "%HOMEDRIVE%%HOMEPATH%"

今更Python 2.7をインストールするのは気が引ける。
伝統的にPython 2.7はドライブのルートにインストールするようにインストーラが作られている。

≫ Read More

2018/09/20 コンピュータ   TakeMe
Tag:Python

WinPython 3.7.0 virtualenvは時間がかかる

pyv8のインストールに失敗,virtualenvを使えばよいのでは,などと考えて今度は,virtualenvをインストールして実行するも,失敗したように見える。が,実際には成功していたという話。
そしてpyv8はインストール失敗。

まず,普通にvirtualenvをインストールする。
pip install virtualenv
でインストールできる。

それから
仮想環境を作るディレクトリ名を指定して
python -m virtualenv take3
などと実行する。

すると,DeprecationWarning: the imp module ....など表示が出てきて止まっているように見えるため,失敗したのかと思っていた。何度試しても同じ表示で止まってしまう(ように見える)

数分後 
Installing setuptools, pip, wheel...done.
まで進んでいてビックリ。
virtualenvの処理に時間がかかるだけの場合があるのでじっくり待ってみてください。

≫ Read More

2018/09/19 コンピュータ   TakeMe
Tag:Python

Python embeddable用に追加モジュールのzipファイルを追加

Python embeddableではモジュールが不足していることがある。使いたいモジュールを追加してzipファイルとして同梱する際に参考になるページはある。

いろいろ確認しているが,numpyのインポートはうまくいっていない。
うまくいきそうなものもあるのだが…

zipimportという仕組みを使用しているだけなので,もしかすると,重いフォルダをzip圧縮しておいてまるでフォルダをパスに追加するかのように
sys.path.insert()でファイルを追加していくということで重いファイルを軽くして配布して,配布先で使用できるようになるというもの。

zipimportの仕組みはかなり凝っている。
自分でよういした簡単なpyスクリプトなら普通に実行することができるだろう。
例えば,以下のような。

# -*- coding: utf-8 -*-

def example1(a):
    return a * 1;



≫ Read More

2018/09/17 コンピュータ   TakeMe
Tag:Python