本記事は 個人開発 Advent Calendar 2019 14日目の記事です。
そしてQiita初投稿です。はじまして。
Python×Kivyというフレームワークを使用して、Windowsアプリを作成しています。
背景
- 紙本を自炊してPDFにした。スッキリ!
- さぁ、iPadで読もう
- 子供にiPad取られた・・・
- Surface買った!さぁ、Surfaceで読もう
- iPadと違ってWindows用の良いアプリ無いな
- Kinoppy(紀伊国屋書店アプリ)良いね!
- これ今勉強中のKivyで作れるかな。
Kinoppy(紀伊国屋書店アプリ)はとても良いアプリで、おすすめです。
アプリ概要
開発環境
AnacondaNavigator
VSCode
Python3.7
Kivy1.11
使用ライブラリ等
他人に頼りすぎて沢山ありますが、メインで使用しているものは以下です。
PDFレンダリング:pdf2image
設定ファイル:ruamel.yaml
アイコンフォント:iconfonts
大変お世話になったサイト
Kinoppy
Kivy
stackoverflow
荒川光線ブログ 本館
そして
Qiita:Kivy
Todo
結構奥が深くて志半ばですが、以下を目指してます。遠い。。
- PDF読込(ローカルPC)
- PDF読込(DropBox)
- 本棚管理(本棚追加&削除)
- D&Dで本の移動(本棚内)
- D&Dで本の移動(別の本棚)
- ビューワ機能(1or2ページ表示、右or左開き指定)
- ビューワ機能(自動目次作成)
- ビューワ機能(検索)
ソースコード他
以下のKivyのソースコードを2つ抜粋して紹介します。
- Scatterによるサムネイルのドラッグアンドドロップ
- Sleiderの右→左の実現
- (おまけ)本棚の作り方
1.Scatterによるサムネイルのドラッグアンドドロップ
サムネイル(本棚に表示される画像)を何秒か掴んだらドラッグアンドドロップします、という事で、画像枠に色を付けます。もしドラッグアンドドロップに入る前に離したら、普通のクリックと見なしてビューワに遷移します。
<DraggableThumbnail@Scatter>:
image_name: ''
image_path: ''
image: image_id
shelf_row: None
shelf_col: None
do_rotation: False
do_scale: False
auto_bring_to_front: True
do_collide_after_children: True
background_color: 0,0,0,0
background_normal: ''
Image:
id: image_id
source: root.image_path
allow_stretch:True
keep_ratio: True
canvas:
Color:
rgb: (1, 1, 1)
Rectangle:
texture: self.texture
pos: self.pos
size: self.size
class DraggableThumbnail(Scatter):
image_name = StringProperty(None)
image_path = StringProperty(None)
shelf_row = NumericProperty(None)
shelf_col = NumericProperty(None)
state = OptionProperty('released',options=['grabed','released'])
img_touched = StringProperty(None)
t = NumericProperty(0)
def __init__(self,**kwargs):
super(DraggableThumbnail,self).__init__(**kwargs)
# ここでClock.schedule_onceしないとサイズ変更出来ない
Clock.schedule_once(self.drag_after_init)
def drag_after_init(self, dt):
self.size_hint = None,None
self.size = self.image.size
# ここでドラッグアンドドロップ用の画像枠だけ作る
with self.canvas:
self.color = Color(rgba = (1,1,1,0))
self.frame = Line(rectangle=(0,0,self.image.width,self.image.height))
def on_state(self,*args):
# 掴んだら画像枠をグレーにします。
if self.state == 'grabed':
self.color.rgba = (0.5,0.5,0.5,1)
# 離したら元に戻します。
elif self.state == 'released':
self.color.rgba = (1,1,1,0)
def time_count(self,*args):
self.t += 0.1
def on_t(self,*args):
if self.t >=0.5:
Clock.unschedule(self.time_count)
self.t = 0
self.state = 'grabed'
self.img_touched = ''
def on_touch_down(self, touch):
self.on_state(touch)
if self.collide_point(*touch.pos):
Clock.schedule_interval(self.time_count, 0.1)
self.img_touched = self.image_name
touch.grab(self)
return True
def on_touch_up(self, touch):
Clock.unschedule(self.time_count)
self.t = 0
if touch.grab_current is self:
if self.img_touched == self.image_name:
self.img_touched = ''
if self.state == 'released':
# ビューワに遷移
app= App.get_running_app()
app.root.chgdisp_viewer(self.image_name)
else:
# ドロップされたのでサムネイル整列
app= App.get_running_app()
app.root.Library.lineup_thumbnail(self,touch)
touch.ungrab(self)
self.state = 'released'
return True
def on_touch_move(self, touch):
Clock.unschedule(self.time_count)
self.t = 0
if self.state == 'grabed':
self.pos = touch.x - self.image.width / 2, touch.y - self.image.height / 2
return True
else:
self.img_touched = ''
2.Sleiderの右→左の実現
海外のPDFViewerで不便に思うのが縦書き(右→左)に対応していない事です。Kivyのスライダーは左→右(下→上)は実現できますが、右から左の設定がありません。あとスライドしている時にページ数も欲しかったのでこちらは部品化しました。ソースはGithubにアップしてあります。こうやって標準部品をカスタマイズするのかーと勉強になりました。もし良ければソースご覧ください。
3.(おまけ)本棚の作り方
ちょうどいい本棚画像が無かったので、作りました。この画像の事です。
作り方はこちらの自分のブログにて、プログラムとは関係ありませんし、どこにも需要が無さそうですが。
最後に
はじめてのQiita投稿とはじめてのAdvent Calendar、12月1日から自分の担当まで時間が過ぎるのが早いこと!!毎日「あーもうすぐ順番が…」のドキドキが、とても良いモチベーションになりました。このイベントが無かったらここまで仕上がってなかったです。参加出来て良かったです。お読み頂きありがとうございました。