WPP
LM22 に天気アプレットを追加する

突然ですが、スマホのメイン画面を左にスワイプすると天気予報表示されますが、地味に便利だと思いませんか?
というわけで LM22 というか cinnamon に天気予報を表示する小ネタです。

他のデスクトップ環境でも同じような感じですが、cinnamon ではデスクトップに表示する desklet やメニューパネル(タスクバー ?) に表示する applet を追加できます。

自分はデスクトップに多くのウィンドウを開きっぱなしにするスタイルなので desklet は向かないので applet を追加することにします。

手順

メニューバーで右クリックし、Panel Settings に入ります。

Weather を選んで + をクリックします。

Applet 追加

Data service は OpenWeatherMap か Open-Metro を選びます。他は多分動きません。API Key は無ければ空でも OK です。

Weather タブ設定

自分の場合 Location タブでは、Manual Location を ON にしないと動作しませんでした。
Location に Tokyo, JP のように表示する場所を設定します。市単位でも検索に引っかかることがあるので色々やってみてください。

Location タブ

検索で見つかるようになれば、下のように天気が表示されます。

動作している様子

参考

Cinnamon Spices

LM22 (Ubuntu 24.04) で pyrealsense2 をセットアップするためにしたあれこれ

結論からいうと pyenv で python 3.11 入れれば OK。

LM22 (Ubuntu 24.04相当) には、python 3.12 が入っていて pyrealsense2 を pip でインストールできなかったので、当初仕方なくビルドしました。

ビルドには成功しましたが、自分の知識では pipenv 環境下に配置することができずに結局は pyenv で python3.11 をインストールし pip しました。
pipenv 環境下でビルドすると仮想環境の lib に make インストールすることになるようでインストールした pyrealsense2 を pipenv から認識することができませんでした。

ビルドの方法はこんな感じ、必要に応じて -dev パッケージは追加してください。

$ git clone 
$ sudo apt install libssl-dev
$ sudo apt-get install libglfw3-dev 
$ sudo apt install  libudev-dev
$ sudo apt install libusb-dev- libusb-1.0-0-dev


$ git clone https://github.com/IntelRealSense/librealsense.git realsense
$ cd realsense
$ git checkout v.2.56.2
$ mkdir build
$ cd build
$ cmake ../ -DBUILD_PYTHON_BINDINGS:bool=true -DBUILD_EXAMPLES:bool=true -DBUILD_PYTHON_DOCS=true

$ make -j4

pythonサンプルは [cloneしたフォルダ]/wrappers/python/examples の中に入っている。

冒頭にも書いている通り pyenv で python 3.11 をインストールした。というのも LM22 (多分 Ubuntu 24.04 も) Python 3.12 以下のバージョンのパッケージは用意されていないので apt でインストールできない。
なので、pyenv を使って以下の手順で回避した。(もちろん pyenv でなくてもいい)

$ curl https://pyenv.run | bash
$ pyenv local 3.11
$ pipenv shell
$ pipenv install pyrealsense2

; エラーがでなければインストールに成功している。
$ python 
Python 3.11.10 (main, Oct 24 2024, 17:33:16) [GCC 13.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pyrealsense2
>>> 

誤って .python-version を消さないようにしなくちゃ。

参考

librealsense/wrappers/python at master · IntelRealSense/librealsense

IME辞書を自動で Synology Drive にバックアップ

最近こっている事の一つにIME辞書にショートカットを登録することがある。そうすると IME 辞書をバックアップしたくなる。

IME 辞書そのものは普通のファイルなので単にコピーするだけで OK ですが、まあ面倒くさい。Win11 で試した限り辞書の保存場所を変える方法はなさそう。

自分の 場合辞書は
C:\Users\ユーザー名\AppData\Roaming\Microsoft\IME\15.0\IMEJP\UserDict
に保存されている。

これをなんとかして Synology Drive のフォルダにコピーできればバックアップができて、それを定期的に実行すれば自動バックアップの完成という訳。

NAS がなくとも、この自動コピーの仕組みでバックアップは実現できます。

手順

  1. 辞書ファイルのコピー

まずは、辞書をコピーするスクリプトを作成する。コピーには個人的な好みで cwRsync を使用する。

こんな感じになる。/cygdrive/c/ からはじめると c:\ の意味になるようだ。

rsync -av /cygdrive/c/Users/172369/AppData/Roaming/Microsoft/IME/15.0/IMEJP/UserDict/* /cygdrive/c/synologydriveのフォルダ/

cwrsync (rsync) は実際に試す前に -n を追加して (-avn) で実行する内容を試した方がいい。特にデリートコマンド系は危険。

もし、Windows標準の Robocopoy を使うならこんな感じ。(恥ずかしながらこのコマンド初めて知りました。)

Robocopy.exe C:\Users\172369\AppData\Roaming\Microsoft\IME\15.0\IMEJP\UserDict\ . C:\synologydriveのフォルダ /XO

Robocopy はかなり複雑なのでちょっと難しい印象。それで避けていたのかもしれない。

スクリプトを書く際に注意しなくてはいけないのは後段のタスクスケジューラで実行する時にカレントディレクトリがシステムディレクトリ(確か system32 だったか)になってしまうので .\ とかするとコピーができずに永遠に終わらなくなったりする。

  1. タスクスケジューラに登録

2つの参考リンクをミックスした感じで

[start] -> tasks と入力してタスクスケジューラを起動する。

新しいタスクの作成にすすみ、名前を適当に入れる。
今回は、コピー元、コピー先ともに自分自身がオーナーのユーザーフォルダなので実行するユーザーを変更する必要はない。

[トリガー]タブは、[毎日]、[繰り返し間隔] [1時間] に設定する。

[操作]タブ、
プログラム: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
引数の追加: 作成したスクリプトのフルパス
自分の環境では ExecutionPolicy を許可ずみなので -ExecutionPolicy Bypass は不要でした。

ちょっと面倒ですがここまですると、 Synology Drive へ定期コピーし Synology Drive が NAS へ同期

することで自動バックアップする一連の流れを設定とすることができました。

参考

cwRsync – Rsync for Windows | itefix.net

Robocopyの基本動作とコマンドオプション解説

Windows10でPowerShellスクリプトをスケジュール実行する – 3テラバイト

タスクスケジューラでPowerShell スクリプトを実行する | Windows 実践ガイド

QEMU のモニタで disassemble したい

先日から Mikan 本をやっているのは既出ですが、QEMU モニタでアセンブラ出力できないことにきづきました。今使っている QEMU は LM22 (Ubuntu 24) レポジトリのものを安直につかっていたのですが、その機能がアクティブになっていないようなので、自前ビルドしました。

公式から 9.1.1 をダウンロードして解凍したあと、./configure すると色々とモジュールが不足kしていると文句を言われます。ので順次インストールしていきます。

結論としては libcapstone-dev をインストールする必要があるようです。

参考

https://download.qemu.org/qemu-9.1.1.tar.xz

Hosts/Linux – QEMU

Remmina でRDP接続した時に IME を使えるようにする

何故か NoaMachine で Windows に接続できなくなったので、Remmina を使うことにした。Remmina は RDP 以外にも色々なプロトコルに対応しているがそんことはどうでもいい。

でタイトルに戻ると、認証情報を入力し画面は表示するが IME の入力がどうしてもできなかった。

三本線のメニューアイコンから Preferences > RDP で [Use client keyboard mapping] のチェックを外すと動作した。

もしかしたら Linux PC には US 配列のキーボードを接続しているのが原因なのかもしれない。というのも接続先の Win11 PCには日本語キーボードが接続されているのでマップに不整合が起きているのかもしれない。

参考

Remmina で RDP 接続したら IME 経由で日本語が入力できなくなった【解決】 | 穀風

LM22 Thinkpad のトラックパッドで2本指スクロール

Linux Mint 22 を Thinkpad で動かしていますが、本体付属のトラックパッドで2本指スクロールができないことに気づきました。普段は外付けトラックボールを使用しているので気にしていなかったのですがせっかくなので直してみます。

Linux Mint 22 をインストールするとトラックパッドそのものは認識してくれていて1本指操作や中央ボタンのスクロールは何もしなくても機能してくれます。

$ sudo apt install xserver-xorg-input-synaptics xserver-xorg-input-evdev
$ synclient VertTwoFingerScroll=1

xserver-xorg-input-all も必要らしいですが、トラックパッドが使えているのであれば恐らく入っているはずです。

これで、GUI で設定してもきちんと2本指スクロールを On / Off できるようになりました。

参考

Ubuntu 18.04LTSで2本指のスクロールをアクティブにする方法

cmake のフラグ一覧

cmake がよくわからないのでメモ。

昨日から続けている librealsense2 ですが、python3.12 で pyrealsense2 を使うためには自前ビルドしなければいけない状況なりました。そして librealsense2 は cmake が使われています。

librealsense2 をビルドする時には例えば -DBUILD_EXAMPLES=true とか指定できるのですが、他のオプションは何があるのだろうということで調べました。

cmake の基本的な知識ですが -L とか -LA をつけると一覧が見れるようです。

libsense2 2.56.1 で自分の環境で実行するとこうなります。

$ mkdir build
$ cd build
$ cmake ..
$ cmake .. -LA
-- Checking internet connection...
-- Internet connection identified
-- Info: REALSENSE_VERSION_STRING=2.56.1
-- Setting Unix configurations
-- No output directory set; using /media/mnishi/opt/ws-sf/rs2/librealsense/build/Release/
-- Fetching pybind11...
CMake Deprecation Warning at build/third-party/pybind11/CMakeLists.txt:8 (cmake_minimum_required):
  Compatibility with CMake < 3.5 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


-- pybind11 v2.10.3 
CMake Warning (dev) at build/third-party/pybind11/tools/FindPythonLibsNew.cmake:98 (find_package):
  Policy CMP0148 is not set: The FindPythonInterp and FindPythonLibs modules
  are removed.  Run "cmake --help-policy CMP0148" for policy details.  Use
  the cmake_policy command to set the policy and suppress this warning.

Call Stack (most recent call first):
  build/third-party/pybind11/tools/pybind11Tools.cmake:50 (find_package)
  build/third-party/pybind11/tools/pybind11Common.cmake:180 (include)
  build/third-party/pybind11/CMakeLists.txt:208 (include)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Fetching pybind11 - Done
-- Fetching pybind11_json...
-- Fetching pybind11_json - Done
-- Building libcurl enabled
-- using RS2_USE_V4L2_BACKEND
-- Fetching nlohmann/json...
-- Using the multi-header code from /media/mnishi/opt/ws-sf/rs2/librealsense/build/third-party/json/include/
-- Fetching nlohmann/json - Done
-- Check for updates capability added to realsense-viewer
-- Check for updates capability added to realsense-depth-quality
-- Fetching recommended firmwares:
-- disable link time optimization for fw project
-- ... https://librealsense.intel.com/Releases/RS4xx/FW/D4XX_FW_Image-5.16.0.1.bin
-- Configuring done (2.2s)
-- Generating done (0.1s)
-- Build files have been written to: /media/mnishi/opt/ws-sf/rs2/librealsense/build
-- Cache values
ANDROID_USB_HOST_UVC:BOOL=OFF
BUILD_CSHARP_BINDINGS:BOOL=OFF
BUILD_CV_EXAMPLES:BOOL=OFF
BUILD_CV_KINFU_EXAMPLE:BOOL=OFF
BUILD_DLIB_EXAMPLES:BOOL=OFF
BUILD_EASYLOGGINGPP:BOOL=ON
BUILD_EXAMPLES:STRING=true
BUILD_GLSL_EXTENSIONS:BOOL=ON
BUILD_GRAPHICAL_EXAMPLES:BOOL=ON
BUILD_LEGACY_LIVE_TEST:BOOL=OFF
BUILD_LEGACY_PYBACKEND:BOOL=OFF
BUILD_MATLAB_BINDINGS:BOOL=OFF
BUILD_OPEN3D_EXAMPLES:BOOL=OFF
BUILD_OPENNI2_BINDINGS:BOOL=OFF
BUILD_OPENVINO_EXAMPLES:BOOL=OFF
BUILD_PCL_EXAMPLES:BOOL=OFF
BUILD_PC_STITCHING:BOOL=OFF
BUILD_PYTHON_BINDINGS:STRING=true
BUILD_PYTHON_DOCS:BOOL=OFF
BUILD_RS2_ALL:BOOL=ON
BUILD_SHARED_LIBS:BOOL=ON
BUILD_TOOLS:BOOL=ON
BUILD_UNITY_BINDINGS:BOOL=OFF
BUILD_UNIT_TESTS:BOOL=OFF
BUILD_WITH_CPU_EXTENSIONS:BOOL=ON
BUILD_WITH_CUDA:BOOL=OFF
BUILD_WITH_DDS:BOOL=OFF
BUILD_WITH_OPENMP:BOOL=OFF
BUILD_WITH_STATIC_CRT:BOOL=ON
CCACHE_FOUND:FILEPATH=CCACHE_FOUND-NOTFOUND
CHECK_FOR_UPDATES:BOOL=ON
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
CMAKE_AR:FILEPATH=/usr/bin/ar
CMAKE_BUILD_TYPE:STRING=
CMAKE_COLOR_MAKEFILE:BOOL=ON
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-13
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-13
CMAKE_CXX_FLAGS:STRING=
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-13
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-13
CMAKE_C_FLAGS:STRING=
CMAKE_C_FLAGS_DEBUG:STRING=-g
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
CMAKE_EXE_LINKER_FLAGS:STRING=
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
CMAKE_INSTALL_BINDIR:PATH=bin
CMAKE_INSTALL_DATADIR:PATH=
CMAKE_INSTALL_DATAROOTDIR:PATH=share
CMAKE_INSTALL_DOCDIR:PATH=
CMAKE_INSTALL_INCLUDEDIR:PATH=include
CMAKE_INSTALL_INFODIR:PATH=
CMAKE_INSTALL_LIBDIR:PATH=lib
CMAKE_INSTALL_LIBEXECDIR:PATH=libexec
CMAKE_INSTALL_LOCALEDIR:PATH=
CMAKE_INSTALL_LOCALSTATEDIR:PATH=var
CMAKE_INSTALL_MANDIR:PATH=
CMAKE_INSTALL_OLDINCLUDEDIR:PATH=/usr/include
CMAKE_INSTALL_PREFIX:PATH=/usr/local
CMAKE_INSTALL_RUNSTATEDIR:PATH=
CMAKE_INSTALL_SBINDIR:PATH=sbin
CMAKE_INSTALL_SHAREDSTATEDIR:PATH=com
CMAKE_INSTALL_SYSCONFDIR:PATH=etc
CMAKE_LINKER:FILEPATH=/usr/bin/ld
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/gmake
CMAKE_MODULE_LINKER_FLAGS:STRING=
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_NM:FILEPATH=/usr/bin/nm
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
CMAKE_READELF:FILEPATH=/usr/bin/readelf
CMAKE_SHARED_LINKER_FLAGS:STRING=
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
CMAKE_SKIP_RPATH:BOOL=NO
CMAKE_STATIC_LINKER_FLAGS:STRING=
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
CMAKE_STRIP:FILEPATH=/usr/bin/strip
CMAKE_TAPI:FILEPATH=CMAKE_TAPI-NOTFOUND
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
COM_MULTITHREADED:BOOL=ON
ENABLE_CCACHE:BOOL=ON
ENABLE_EASYLOGGINGPP_ASYNC:BOOL=ON
ENFORCE_METADATA:BOOL=OFF
FORCE_LIBUVC:BOOL=OFF
FORCE_RSUSB_BACKEND:BOOL=OFF
FORCE_WINUSB_UVC:BOOL=OFF
GIT_EXECUTABLE:FILEPATH=/usr/bin/git
HWM_OVER_XU:BOOL=ON
IMPORT_DEPTH_CAM_FW:BOOL=ON
JSON_BuildTests:BOOL=OFF
JSON_CI:BOOL=OFF
JSON_Diagnostics:BOOL=OFF
JSON_DisableEnumSerialization:BOOL=OFF
JSON_GlobalUDLs:BOOL=ON
JSON_ImplicitConversions:BOOL=ON
JSON_Install:BOOL=OFF
JSON_LegacyDiscardedValueComparison:BOOL=OFF
JSON_MultipleHeaders:BOOL=ON
JSON_SystemInclude:BOOL=OFF
LIBUSB_INC:PATH=/usr/include/libusb-1.0
LIBUSB_LIB:FILEPATH=/usr/lib/x86_64-linux-gnu/libusb-1.0.so
OPENGL_EGL_INCLUDE_DIR:PATH=/usr/include
OPENGL_GLES2_INCLUDE_DIR:PATH=/usr/include
OPENGL_GLES3_INCLUDE_DIR:PATH=/usr/include
OPENGL_GLX_INCLUDE_DIR:PATH=/usr/include
OPENGL_INCLUDE_DIR:PATH=/usr/include
OPENGL_egl_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libEGL.so
OPENGL_gles2_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libGLESv2.so
OPENGL_gles3_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libGLESv2.so
OPENGL_glu_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libGLU.so
OPENGL_glx_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libGLX.so
OPENGL_opengl_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libOpenGL.so
OPENGL_xmesa_INCLUDE_DIR:PATH=OPENGL_xmesa_INCLUDE_DIR-NOTFOUND
OPENSSL_CRYPTO_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libcrypto.so
OPENSSL_INCLUDE_DIR:PATH=/usr/include
OPENSSL_SSL_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libssl.so
PKG_CONFIG_ARGN:STRING=
PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config
PYBIND11_FINDPYTHON:BOOL=OFF
PYBIND11_INSTALL:BOOL=OFF
PYBIND11_INTERNALS_VERSION:STRING=
PYBIND11_NOPYTHON:BOOL=OFF
PYBIND11_PYTHONLIBS_OVERWRITE:BOOL=ON
PYBIND11_PYTHON_VERSION:STRING=
PYBIND11_SIMPLE_GIL_MANAGEMENT:BOOL=OFF
PYBIND11_TEST:BOOL=OFF
PYTHON_EXECUTABLE:FILEPATH=/media/mnishi/opt/ws-sf/rs2/.venv/bin/python
PYTHON_INSTALL_DIR:PATH=/media/mnishi/opt/ws-sf/rs2/.venv/lib/python3.12/site-packages/pyrealsense2
PYTHON_LIBRARY:FILEPATH=/usr/lib/x86_64-linux-gnu/libpython3.12.so
REALSENSE_FIRMWARE_URL:STRING=https://librealsense.intel.com
UDEV_INCLUDE_DIRS:PATH=/usr/include
UDEV_LIBRARIES:FILEPATH=/usr/lib/x86_64-linux-gnu/libudev.so
UNIT_TESTS_ARGS:STRING=
glfw3_DIR:PATH=/usr/lib/x86_64-linux-gnu/cmake/glfw3
pkgcfg_lib_UDEV_PKGCONF_udev:FILEPATH=/usr/lib/x86_64-linux-gnu/libudev.so
pkgcfg_lib__OPENSSL_crypto:FILEPATH=/usr/lib/x86_64-linux-gnu/libcrypto.so
pkgcfg_lib__OPENSSL_ssl:FILEPATH=/usr/lib/x86_64-linux-gnu/libssl.so
(rs2) mnishi@tpe14:/media/mnishi/opt/ws-sf/rs2/librealsense/build$ 

参考

cmakeプロジェクトの設定項目一覧を表示させる – かみのメモ

Linux Mint 22 に librealsense2 をインストール

今日はちょっと話題を変えて intel RealSense を試す機会があり早速 LM22 にインストールしてみた

基本的には公式の手順通りなのだが、Linux Mint なので Ubuntu のコードネームを正しく設定してやる必要がある。

通常なら lsb_release -csubuntu-distro-info -cs に変更すれば OK なようだが、librealsense2 は Ubuntu 24 (noble) には完全に対応していないようで librealsense2-utils とかが存在しない

なので一つ前の jammy にしてみる。

; pgp キーの追加
$ sudo mkdir -p /etc/apt/keyrings
$ curl -sSf https://librealsense.intel.com/Debian/librealsense.pgp | sudo tee /etc/apt/keyrings/librealsense.pgp > /dev/null

; lsb_release だと LM22 のコードネーム wilma を返してくる
; $ echo "deb [signed-by=/etc/apt/keyrings/librealsense.pgp] https://librealsense.intel.com/Debian/apt-repo `lsb_release -cs` main" | \
sudo tee /etc/apt/sources.list.d/librealsense.list

$ echo "deb [signed-by=/etc/apt/keyrings/librealsense.pgp] https://librealsense.intel.com/Debian/apt-repo jammy main" | \
sudo tee /etc/apt/sources.list.d/librealsense.list

$ sudo apt-get update

$ sudo apt install librealsense2-dkms librealsense2-utils
$ sudo apt isntall librealsense2-dev librealsense2-dbg

; とりあえずビューアが動くか確認
$ realsense-viewer

; キャリブレータと依存ライブラリ
$ apt install libgult3.12 librscalibrationtool
$sudo ln -s /usr/lib/x86_64-linux-gnu/libglut.so.3.12 /usr/lib/x86_64-linux-gnu/libglut.so.3

ubuntu-distro-info コマンド使えば Ubuntu のコードネームを簡単にとれることを覚えておこう。今まで気づきませんでした。docker とか virtualbox とかの独自リポジトリで配布している時に便利に使えそう。

それにしても apt とかのリポジトリでどのコードネームが実際ホストしているかってどうやって調べたら良いのか?まだまだ知らないことは多い。

参考

librealsense/doc/distribution_linux.md at master · IntelRealSense/librealsense

Realsense カメラキャリブレーション 400シリーズ D415 D435 #RealSense – Qiita

KivyMD の NavigationDrawer に RecycleView を追加するサンプル

引き続き、Kivy です。

今回は、KivyMD の NavigationDrawer の中に RecycleView を突っ込んでみます。Kivy / KivyMD はここのコンポーネントを動作確認する分には特別難しいことはありませんが、複数組み合わせるとトタンになかなかいい感じに配置することができないのが難点だと思う。(自分の理解の浅さのせいかもしれないが、HTML/CSS の方がまだましに感じます。)

提示するサンプルを実行するとこんな感じになります。前回と同じように Appbar が画面上部にあり、 Appbar のアイコンを押すと、NavigationDrawer が表示されます。その NavigationDrawer の中に 果物の名前のリストを表示しています。

Appbar のアイコンが左で、ドロワーが右から出てくるのは違和感があるかもしれませんが anchor の確認のためにあえて行っています。

環境

  • Kivy 2.3.0
  • KivyMD 2.0.1.dev

コード

from kivy.lang import Builder

from kivy.properties import StringProperty

from kivymd.app import MDApp
from kivymd.uix.label import MDLabel
from kivymd.uix.recycleview import MDRecycleView


KV = '''
MDScreen:

    MDNavigationLayout:
        # size_hint_x: 1

        ScreenManager:
            MDScreen:

                MDBoxLayout:
                    md_bg_color: self.theme_cls.secondaryContainerColor
                    orientation:'vertical'
                    
                    MDTopAppBar:                        
                        MDTopAppBarLeadingButtonContainer:
                            MDActionTopAppBarButton:
                                icon: 'menu'
                                on_release: nav_drawer.set_state('toggle')
                            
                        MDTopAppBarTitle:
                            text: 'this is AppBar'
                            pos_hint: {'center_x': .5}
                            
                    MDLabel:
                        text: "I'm MDLabel"

        MDNavigationDrawer:
            anchor: 'right'

            MDBoxLayout:
                orientation: 'vertical'

                MDNavigationDrawerLabel:
                    text: 'drawer items!!'
                    icon: 'format-list-bulleted'

                MDNavigationDrawerDivider:

                NvDrawerRecycleItem:                    
                    id: rv
                    padding: 0, nav_drawer.height, 0, 0
                    viewclass: 'Food'
                    RecycleBoxLayout:
                        size_hint: (1, None)
                        height: self.minimum_height
                        orientation:'vertical'

<NvDrawerRecycleItem>:

<Food>:
    text: 'name: {}'.format(self.item)
    adaptive_size: True
    padding: 0, dp(16), 0, dp(16)

'''

class Food(MDLabel):
    item = StringProperty('')

class NvDrawerRecycleItem(MDRecycleView):
    pass


class TestNavigationDrawer(MDApp):
    def build(self):
        self.theme_cls.theme_style = 'Dark'  # or 'Light'
        return Builder.load_string(KV)
    
    def on_start(self):
        rv = self.root.ids.rv
        rv.data = (
            { 'item': it }
            for it in [
                'Apple', 'Banana', 'Cherry', 'Grape', 'Lemon',
                'Mikan', 'Orange', 'Pear', 'Lychee', 'Strawberry',
                'Peach', 'Fig'
            ]
        )


TestNavigationDrawer().run()

公式のサンプルでは MDNavigationDrawerMenu の中に Drawer の中身を入れてるのですが、そうすると RecycleView と MDNavigationDrawerMenu の間に大きな隙間ができてしまい。どうしても制御することができませんでした。

また、MDBoxLayout: orientation: ‘vertical’ で囲ってあげないと ドロワー系のアイテムと RecycleView が横並びになってしまいました。

そのため、上のようなサンプルコードになりました。


        MDNavigationDrawer:
            id: nav_drawer
            anchor: 'right'

            MDBoxLayout:
                orientation: 'vertical'

                MDNavigationDrawerMenul:
                    MDNavigationDrawerLabel:
                       text: 'drawer items!!'
                       icon: 'format-list-bulleted'

                      MDNavigationDrawerDivider:

                NvDrawerRecycleItem:                    
                    id: rv
                    padding: 0, nav_drawer.height, 0, 0
                    viewclass: 'Food'
                    RecycleBoxLayout:
                        size_hint: (1, None)
                        height: self.minimum_height
                        orientation:'vertical'

今作りたいものをやるのにドロワーの中にリスト入れればいけるんじゃね?と安直に考えてやってみたがなかなかしんどかった。Kivy の道はきびしい。

KivyMD の Appbar 画面上部にピッタリに配置する方法

さあ、今日も Kivy の話です。

KivyMD にはあたかも Android アプリのような Appbar というコンポーネントがあります。これを画面のトップに配置して下部分に大きさピッタリのコンテンツを配置する方法のメモです。

やりたいことは、2つあります。

  1. Appbar を画面トップに配置する。
  2. 空いた下の領域いっぱいにコンテンツを表示する。

結果はこんな感じになります。

画像を入れる

環境

  • Kivy 2.3.0
  • KivyMD 2.0.1.dev

最終的なサンプル

from kivy.lang import Builder

from kivymd.app import MDApp

KV = '''
MDScreen:
    MDBoxLayout:
        orientation: 'vertical'
        padding: 0,app_bar.height, 0,0      # L T R B

        MDBoxLayout:
            md_bg_color: 0.2,0.2,0.4, 1
            MDLabel:
                text: 'text label'
                valign: 'bottom'

    MDTopAppBar:
        id: app_bar
        pos_hint: {'top': 1}
        
        MDTopAppBarLeadingButtonContainer:
            MDActionTopAppBarButton:
                icon: 'menu'
                
        MDTopAppBarTitle:
            text: 'top appbar'
        
        MDTopAppBarTrailingButtonContainer:
            MDActionTopAppBarButton:
                icon: "github"
'''

class MainApp(MDApp):
    def build(self):
        self.theme_cls.theme_style = 'Dark'  # or 'Light'
        return Builder.load_string(KV)
    
if __name__ == '__main__':
    MainApp().run()

画面トップに配置

自分が試した限りでは、 TopAppBar を公式サンプルのまま配置しただけでは画面の上部に表示することはできませんでした。(これバグ何じゃないだろうか ?)

なので pos_hint に ‘top’: 1 を設定してやります。kivy では画面左下が原点になるので ‘top’: 1 は画面の最上部を意味します。(0 – 1.0 が入り割合を示すらしい。)

    MDTopAppBar:
        id: app_bar
        pos_hint: {'top': 1}
        

コンテンツを Appbar の下ギリギリまで配置する

次に、コンテンツ領域の制御です。ここはなにも制限しないと親の大きさいっぱいまで使ってしまいます。つまりコンテンツ領域が Appbar で隠れるか、 Appbar を隠すかしてしまいます。(これは .KV 内の定義の順番によるっぽいです。)

Stack overflow で見つけた解決策は padding を設定して下の領域の大きさを明示的に制限するというものでした。こんな感じです。

padding に設定してやるのは Appbar の高さなので id: 属性を追加します。

追加した id (Appbar) の高さ分 padding でコンテンツ領域を下げてやります。

    MDBoxLayout:
        orientation: 'vertical'
        padding: 0,app_bar.height, 0,0      # Left Top Right Bottom

   # いろいろ省略

    MDTopAppBar:
        id: app_bar
        pos_hint: {'top': 1}
        # size_hint_x: 1

Kivy / KivyMD は配置周りの挙動がよくわからないのが辛い。

参考

python – How do i make an MDBottomAppBar appear on top of a list view in KivyMD – Stack Overflow

Appbar — KivyMD 2.0.1.dev0 documentation