頭の中は異空間

ものづくり中心

【Python】【Tk】treeview(表)に横スクロールバーを付ける

treeviewで横スクロールが出来ないと不便なのでつけよう、というものです。表以外の形式でも出来ると思います(未検証)。

 

コードとしては

frame = ...(frame初期化)
tree = ...(treeview初期化)
tree.pack()
hscrollbar = ttk.Scrollbar(frame, orient = tk.HORIZONTAL, command=tree.xview)
tree.configure(xscrollcommand=lambda f, l: hscrollbar.set(f, l))
hscrollbar.pack(fill='x')

で出来ます。

先にtree.pack()しておくことで、スクロールバーを表の下部につけることが出来ます。見て分かる通り同じframe内にtreeviewおよびスクロールバーを収める必要があります。

hscrollbar.pack()するときfill='x'がないと、スクロールバーのサイズが最小化されてしまって使い物になりません。

 

余談ですが、下記リンクの

autoscroll

を使うことで、ウィジェットのサイズによってスクロールバーをつけたり消したり出来ます。

python 2.7 - Horizontal scrolling won't activate for ttk Treeview widget - Stack Overflow

 

なお、縦スクロールバーも同様につけることが出来るものの、デフォルトでホイールに縦スクロールが対応しているようなので、わざわざつける必要があるのかは疑問。デザイン面を考慮するなら、ですね。

【Python】【Tk】treeview(表)の選択状態についての注意点

ttk.treeviewの表形式で登録データを総入れ替え(delete→insert)なんかするときに悩むであろう罠について。

 

データをすべてtreeview.deleteしたとき、選択中だったデータの選択状態が強制的に外れます

明示的に言えば、treeviewを見た目で選択した状態の「選択」と内部的に選択した状態の「フォーカス」に分かれます。これを元に戻すには、「選択」と「フォーカス」の2つを動的に行う必要があります。

 

# データ全削除
tree.delete(*tree.get_children())

この時点で選択、フォーカスの2つが外れた状態になっています。そのため、本当の意味で表のデータを再選択するには下記(1), (2)の双方が必要です。

# (1)データのフォーカス(プログラム上で内部的に選択した状態)
tree.focus(iid)

 

# (2) データの選択(見た目上で選択された状態)
tree.selection_set(iid)

 

focus(iid)することで、例えば下記のように選択中のデータを取得できたりします。

focused_record = tree.item(tree.focus())['values']

また、selection_set(iid)することで見た目的にもどれを選択中か見せられるのでユーザにとっても親切な作りになります。

 

肝心のiidはデータをinsertするときに返り値として取得可能です。

for record in data:
iid = tree.insert("","end",values=(record))

 

あとは、全データ(data)のループ内でfocused_record == recordのときにfocus, selection_setすることで再選択を実現できます。

【Python】【Tk】Tkのtreeview(表)のヘッダ部分のクリックイベント設定方法

1時間くらいどん詰まりしたので覚書。

 

例えばこんな感じのテーブルがあって、お客様氏名とか郵便番号あたりの行をクリックしたときの挙動をつけたいとき。

f:id:notwo:20180615000844p:plain

 

ttk.Treeviewを継承したクラス内で実装する前提です。

イベント設定を

self.heading(番号(連番だと楽), text=表示したい名前, command=コールバック関数)

こんな感じにして、

コールバック関数内で

x = self.winfo_pointerx() - self.winfo_rootx()
self.identify_column(x)

とすると、どのヘッダがクリックされたかを、#~の形で取得出来ます(厳密にはどのカラムがクリックされたかの情報)。

 

たったこれだけで出来ます。

とはいえ、リファレンスを隅から隅まで見てもそれっぽい非常に旨味なメソッドがなかったのでやり方はこれしかないと思います。

 

やってることは画面に表示しているx座標をもとにidentify_column()でヘッダ名を特定しているだけです。クリック時のマウスカーソルx座標からtreeview自体のx座標を引けばクリック時のtreeview上の位置が特定出来ます。取得した番号から#を取り除いてcolumn()やheading()に渡せば、カラムやヘッダの設定を取得まで出来ます。

 

この手のイベント設定で考えられる使い道はたぶん、ソートしたいとき位ではないかな...?

【Windows10】【Python】pyinstallerを使うとき注意すべきこと

Windows10でpython+Tkで書いたツールをexe形式にしたいとき、pyinstallerを選択しました。で、結構躓いたので後学のために注意点をまとめます。

 

 

Pythonのバージョン

一番大事なことです。

まず私が試したのはPython Releases for Windows | Python.orgPython 3.7.0b5 - 2018-05-30です。これで

pyinstaller -F -w xxx.py

とかすると、確かにexeは作られるんですが実行しようとしても何も起きません。おそらく裏でコケてエラー吐いてると思います。

pyinstallerはまだpython3.7をサポートしていない可能性大です。

-->python3.6.5でやり直したところうまくいきました。

3.6が大丈夫というのは

PyInstallerがPython3.6をサポートしてくれた

で確認しました。

 

インポートファイル

ファイルが複数に分かれていて依存関係がある場合、それらも含めてビルドしないと失敗します。

--paths="`ここに含めたいパス"をつけてpyinstaller実行しましょう。

ex) pyinstaller -F -w xxx.py --paths="./modules"

※xxx.pyでエントリポイントのあるファイルを、--pathsでそこからimportしているファイルのあるディレクトリをすべて指定すること。

 

アラートがいっぱい出る

7477 WARNING: lib not found: api-ms-win-crt-stdio-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7547 WARNING: lib not found: api-ms-win-crt-runtime-l1-1-0.dll dependency of
c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7625 WARNING: lib not found: api-ms-win-crt-heap-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
7703 WARNING: lib not found: api-ms-win-crt-time-l1-1-0.dll dependency of c:\users\~~~~\appdata\local\programs\python\python36\DLLs\_ssl.pyd
...

上記メッセージだけではなんのことやら...といった感じですが、この辺の投稿によればWindows 10に起因する問題の模様です。更に、Windows Vista/7/8ではwarningを抑えるためのdll(つまりwin10で足りない部品)があるとのこと。

しかしgithubの同スレの上部の投稿にある通り、warningが出ていても動作するexeファイル作成自体はできるようで、私もたくさんのエラーが吐かれているにもかかわらず、正常動作するexeファイル作成には成功しています。

どうしてもwarningを消したい、という場合は先程のcodewarrior0氏の言う

so the only thing to do is to install the VC 2015 runtime on the Vista/7/8 machine.

をやれば良いと思います。そこから先は軽く読んだもののこれといった対処法は書かれてないです(私は試していないので↑で出来る!とは断言は出来ませんが...)。

他に何某かのエラーが出てexeが作れない、となったら再び上記warningを疑えば良いのかなと...

 

 

【Windows10】[Windows10]PCの調子がおかしくなったとき用の修理メモ

最近、ドスパラで買ったデスクトップPCのパーツがイカれてきたので、この機会にやったことと起きた現象をメモ。

 

今回起きた現象

  1. 電源は付くがHDDが全くつかない、ディスプレイに全く表示されない
  2. 途中でHDDランプが全く点灯しなくなる

 

1について

急に画面が全くつかなくなり、強制終了してつけ直すとHDDランプすらつかない→こうなるとchkdskすら出来ず、HDDの故障を疑う→分解してHDD(C, Dドラ)を取り出し、診断用の製品(名前忘れた)で動作チェック→問題見当たらず。

 

2について

グラボを外したのに調子が悪いのでHDD不良を再度疑うがCrystalDiskInfoでは正常と出るので問題なさそう、CPUが古くパワーが足りてない疑惑があるためグラボをつける必要が出てきた。

→PCゲームや動画を見なくてもフリーズが頻発するためCPUの負荷が高まったのが原因とかんがえられる

 

実は一昨年あたりに一度HDDを交換しておりHDDがそんなに早く壊れるとは思えないので、冷静になってみればHDDより先に他の周辺パーツに目を向けられたかもしれないです。

 

やったこと

1→HDDチェック、グラボ取り外し

2→HDDチェック、グラボ付け替え

 

PCを買ったのが2011年なので、実に7年近くも使っているのでガタが来てもおかしくないということでパーツ交換をしました。

まるごと買い替えだとそれはそれで安心感は有りますが出費がひどくなるし色々設定し直しでただただ面倒という欠点もあります。安く済ませられる部分は安く済ませるのが賢い解決策だと思います。

 

1について、グラボが原因でない場合はCMOSが悪さをしている可能性もあるということで、その場合はCMOSクリア(取り外して5分間くらい放置)、それでも駄目なら電池買い替えまでありえました。

 

結局悪さをしていたのは古いグラボで、これを買い換えることで無事解決。

【Django】MacでCommunity版PyCharmでDjango環境を触れるようにする + herokuにデプロイまで

Herokuを始めるとき、getting-statedでなく、自分の手元のDjangoプロジェクトをherokuにデプロイすることもできます(むしろこっちが普通かも)

pythonにはPyCharmという便利なSDKがあるので、使えるようにしたいところ。

 

Community版PyCharmではDjangoプロジェクト作成が出来ないので、PyCharmでは予め作ったDjangoプロジェクトを読み込むだけとしましょう。

 

 

PyCharmのインストール

あえて解説するまでもないので詳細は割愛します。

 

Djangoプロジェクトの作成

インストールが終わったら、下記コマンドを実行してDjangoのプロジェクトを作成しましょう。

cd ~/PycharmProjects
# まだなにもない
ls
# プロジェクト作成。ここでは「myMenu」とします。
django-admin startproject myMenu
# 生成物を確認
ls

ここまでで最低限のモノが揃いましたので、PyCharmで開きます。

f:id:notwo:20180520133704p:plain

開くとこんな感じ

ここからエディタをPyCharmとして実装を進めて行きます。

念のため、一応ローカルサーバが立ち上がることを確認します。

f:id:notwo:20180520133359p:plain

こんな画面が出ればOK

herokuへデプロイ

以下コマンドでherokuデプロイ用のローカルgitリポジトリを作成~デプロイまでを行います。

cd myMenu
git init git add ./ git commit heroku create アプリ名※

※Name must start with a letter and can only contain lowercase letters

ここでは「testpythonmenu」としました。

作成するとurlが出てくるので開いてみましょう。

f:id:notwo:20180602205033p:plain
f:id:notwo:20180602205048p:plain

こんな画面が出ればOK(.comの方)

現時点で

git push heroku master

をしても正しく動きません。rejectされるので、pushする前に必要な作業を済ませます。具体的には、

This occurs when Heroku cannot detect the buildpack to use for this application automatically.

とか出るので、

elements.heroku.com

にある通りの対策をします。

その前に、

devcenter.heroku.com

に従い、Procfileをプロジェクトルートに生成します。Procfileは↑公式サイトの通りで問題ないです。

他にはgunicornというwebサーバが入ってないといけないので合わせて入れます。

gunicornのインストールにはpipenvが必要なので、

# プロジェクトルートにいることを確認
pwd
# 1つずつインストール
pip install pipenv pipenv install gunicorn pipenv install django-heroku

と実行していきましょう。この時点でPipfileおよびPipfile.lockが作られます。

gunicornのインストールに失敗したら、おそらく下記の通りにすればうまくいきます。

www.lifewithpython.com

install成功したら、settings.pyへの記述も忘れずに(import django_herokuの記述も必要です)!

以上を設定してcommitしたら、

heroku buildpacks:set heroku/python

として今度こそpushします。

それでも、

remote:  !     Push failed: An unhandled error occurred, please try again shortly. See https://status.heroku.com/ for current Heroku platform status. If the problem persists, please contact https://help.heroku.com/ and provide Request ID fb0fb17b-ec7f-870d-28ca-7e53f9960147.
remote:  !     Please try pushing again.
remote:  !     If the problem persists, see http://help.heroku.com/ and provide Request ID fb0fb17b-ec7f-870d-28ca-7e53f9960147.

などという謎エラーを吐くことがありますが、こういうときは再度pushし直してください。うまくいくはずです。

これで出力されたURLにアクセスすると

 

f:id:notwo:20180605015519p:plain

無事に設定が終わったことがわかります。

 

今までの手順に異常があると、URLアクセス時に

f:id:notwo:20180603153225p:plain

となります。

heroku logsでログを見れるので、エラーメッセージをもとに修復すること。

 

番外編

requirements.txtがあるのにProcfileを生成してしまった

なんとrequirements.txtが同じディレクトリに残っていると、Pipfileはrequirements.txtの内容を自動で読みに行ってその内容を勝手にインポートしやがります。このせいで、その後pipenv installしたパッケージによっては依存関係がめちゃくちゃになってエラーを吐く原因になります。

こうなると解決は困難なので、一度herokuアプリからすべて消して作り直したほうが速いです。

まずないと思いますが、昔の名残でrequirements.txtが残っている場合は先に削除してからpip installするように!!

 

Pipfileがあってbuildpackしたのに同じエラーでpushできない!

こんなときは

Ruby on railsのtutorialをherokuに突っ込んだ時に躓いたこと

と同じ問題な可能性が高いです。pipenv installするときは必ず、プロジェクトルートディレクトリにcdしてから行うこと!

 

【雑談】後で振り返って力が湧く様なバックボーンを持つべきだと思う話

久々にHDDを整理していたら懐かしいものが大量に出てきます。大掃除の時、引越し前の片付けの時にも同じことが頻繁に起こるものだと思いますが、このとき余計な寄り道をしてしまうのは仕方ないと思います(笑)

でもそこで学生時代の課題とか成績表などがまるごと入っているzipが見つかったので過去を振り返るようにチラチラ見ていました(懐古)。

ここから物凄い自分語りをします(´ . .̫ . `)↓↓

 

 

普通大学に入ると遊んでばかりというイメージがありますが(残念なことに実際は大半がそうだと思う)、私の場合確かに1、2年時には大したこともやらずに取れる単位だけ適当に取ってその場しのぎしていたような記憶しかありません。しかしその翌年からは違います。3年時には

  • 前期、後期で取れる単位総計50をすべて取得→自分のいたところは情報系で、真面目にやっても落とす人は落とす鬼畜講義がいくつもあった
  • 専門学校(夜間)とのダブルスクール→自腹
  • IPA基本情報処理試験合格→もちろん自腹
  • 四輪免許取得→もち(ry

を全部達成しました。その代わりバイトやサークルなんてやってないしやる暇なかったし、やらなくて別に良かったです。う~ん、学生らしくない!(笑)

社会人になってからも1社目では

  • 誰が何を知っているかすらわからない、スラム街状態のサービス手順書やwikiを整理したり新設してまとめる
  • テスト環境を新たに作る
  • 手順書1つなかった複数の本番サーバ再起動をほぼ実害無しで終了させる

etc

という感じで無茶苦茶をやってきました(笑)勿論こんなことしないに越したことはないです、が無茶した経験があるので多少のことではへこたれないようにはなりました。

精神が病んでしまわない範囲でならキツイ経験は確かに大事、でもそれで無理をしすぎて倒れたら意味がないのであくまで自分との相談のうえでこのような無茶は成り立ちます。

その後やったことといえば

  • 知人のサイトをwordpressに置き換え
  • そのサイトと別にAWSにて申し込みフォームの作成

くらいです。このくらいが丁度良いです。

社会に出てからいつどこでどんな理不尽ゲーを強要されるか、無茶振りされるか分からないので学生時代に絶対何かしらの耐性をつけておいたほうが良いです。勿論、パワハラセクハラが横行するような組織なら速攻抜けるに限ります。

どんな些細なことでも良いのでこういう「過去に頑張ったエピソード」を持っておくと、くじけたときにも立ち直りが意外と速く出来たりします。勿論、面接のアピールのために意味不明なことを頑張るのとは違います。

さて吐いてスッキリしたところで今年は何をしよう?

 

あ、そうだ(唐突)

去年にやっと前屈で手のひら張り付き10秒キープが出来るようになりました。ストレッチは気持ち良いし怪我防止になるのでやりましょう。