見出し画像

RaspberryPiでwxPython

インストールしたいだけなのに色々と苦労して訳わからなくなったので、もう一度クリーンインストールから頑張ってみます。
本記事は、現在進行形で試しているメモです。

前回までやったことと問題点

wxPythonを簡単に使いたいけど、ビルドに時間がかかりしかもエラーが出るという状態になった。
思案に暮れていたところ、aptでwxGlageがインストールできるらしいことがわかった。
依存関係が解決されれば自動的にwxPythonは入るはず、という目論見は当たっていて、wxPythonがインストールされた。

しかし、簡単にGUIアプリを作るくらいはできるのだが、wx.DCを使ったところで不具合発生。具体的には、DrawBitmapを使ったときにwxが動かなくなる様子。y座標を1にすると一応動いたりと、良く分からない。
バージョンの関係がおかしいらしい?

参考ページ

考えていることメモ

pythonはバージョンアップする必要がある?

wxPythonはpipでインストール可能だけど、インストールの依存関係は解決しておく必要がありそう。
上記参考ページのwxPyWikiのほうが情報が新しそうだが。。。

やったことメモ

依存関係のインストール(※)

$ sudo apt-get update
$ sudo apt-get install dpkg-dev build-essential libjpeg-dev libtiff-dev libsdl1.2-dev libgstreamer-plugins-base0.10-dev libnotify-dev freeglut3 freeglut3-dev libwebkitgtk-dev libghc-gtk3-dev libwxgtk3.0-gtk3-dev
$ sudo apt-get install python3.7-dev

特にエラーはなかった。

コマンドラインよりpip

$ sudo pip3 install wxpython3

これはエラーになった。404 client error…見つからなかったらしい。

ちなみにビルド済みWhlでは?

ビルド済みパッケージが用意されているかも、と見た所ではDebianは用意されている。
RaspberryPiのOSはDebian系なのでもしかしたら…と思ったけど、やっぱりダメでした。

$ pip3 install https://extras.wxpython.org/wxPython4/extras/linux/gtk3/debian-10/wxPython-4.1.1-cp37-cp37m-linux_x86_64.whl
wxPython-4.1.1-cp37-cp37m-linux_x86_64.whl is not a supported wheel on this platform.

というわけで。

コツコツコツコツ、コンパイル

wxPyWikiでも紹介されている通り、ソースからコンパイルすることにしました。
ただ、18時間以上かかるみたいなこと書いてある気がします。(英語苦手)

前提として、上記※の依存関係のインストールが済んでいる状態です。

wxPyWikiのページに紹介してあるソースファイル「wxPython-4.0.7.post2.tar.gz」をダウンロードして解凍します。

解凍してできたディレクトリに移動して、コンパイル、インストールをします。

$ cd wxPython-4.0.7.post2
$ pip3 install -r requirements.txt
$ python3 build.py build bdist_wheel

(ここで18時間以上待つ)

$ pip3 install wxPython-4.0.7.post2-cp37-cp37m-linux_armv6l.whl

…で、どうなったかといいますと、まずインストールはできました。
import wx をしても、ちゃんと呼び出せています、よしよし。

そして、問題のwx.DCでのDrawBitmapは、結局うまく行きませんでした。
というか、wxGladeでインストールしたときと同じ状況が再現されました。
うーん、これは単純にバグを発見したのでしょうか・・・?

問題の症状をもう一度確認

・使用したpythonプログラムは、Lubuntuで問題なく実行できることを確認したものである。もともと、時計を作ろうとしたものなのでゴミが残っているのはご容赦。

import wx
class MyWindow(wx.Frame):
   def __init__(self, parent=None, id=-1, title=None):
       wx.Frame.__init__(self, parent, id, title)
       self.panel = wx.Panel(self, size=(320, 240))
       self.panel.SetBackgroundColour('WHITE')
       self.timer = wx.Timer(self)
       self.Bind(wx.EVT_TIMER, self.OnTimer)
       self.Fit()
       self.bmp = wx.Bitmap(320, 240)
       self.timer.Start(1000)
       
   def OnTimer(self, event):
       cdc = wx.ClientDC(self.panel)
       bdc = wx.BufferedDC(None, self.bmp)
       
       bdc.SetPen(wx.Pen('white'))
       bdc.SetBrush(wx.Brush('white'))
       (w, h)= self.panel.GetSize()
       bdc.DrawRectangle(0, 0, w, h)
               
       bdc.SetFont(wx.Font(24, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
       bdc.SetTextForeground('green')
       bdc.DrawText('wxPython', 0, 0)

       cdc.DrawBitmap(self.bmp, 0, 0)

if __name__ == '__main__':
   app = wx.App()
   w = MyWindow(title='BasicClock')
   w.Center()
   w.Show()
   app.MainLoop()

・BufferdDCを使用した場合に、DrawBitmap(dc, 0, 0)をした場合に、それ以降のwx.DCは表示が止まってしまう。なお、ClientDCのオブジェクトをBufferdDCにあらかじめ渡しておいて自動で転送させる方法(上記のwx.BufferdDCにNoneではなくcdcを指定する)でのルーチン終了時転送タイミングでも同様。また、Blitで座標(0, 0)に転送した場合も同様。

・DrawBitmapの転送先座標を、(0, 1)、(1, 0)のようにずらすと、問題なく転送できる。このとき、座標を指定したとおりに転送されるので、0行目、0列目が空白になる。Blitでも同様。

さて、何から手を付けたものか。。。

上「cdc.DrawBitmap(self.bmp, 0, 1)」にした場合
下「cdc.DrawBitmap(self.bmp, 0, 0)」にした場合

画像1

画像2



この記事が気に入ったらサポートをしてみませんか?