質問編集履歴

5 解決策を追加

BlueBits

BlueBits score 44

2018/07/18 18:26  投稿

kivy + mqtt on_message時の際の表示エラーの解決方法
**Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6 エラーが発生します。**
**原因と、解決策についてご教示いただけますと幸いです。**
**プログラムの目的に沿えば別の方法でも問題ありません**
**質問の最後に成功例を掲載いたしました。**
# プログラムの目的
ScreenManagerにてmqttから通信がきた場合、Screenを切り替える
その際、通信内容からScreenに表示する画像を決める
# 発生内容
** on_messageにて取得後、切り替え操作の際,切り替え後のScreenにImaegeがあると発生する**
以下は発生したエラーを切り分けるため、縮小したプログラムです。
mqttで何かしらきたらScreenを切り替えるだけのものです。
```python
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait1.png'
""")
class Charactor(Image):
   pass
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.changeScreen()
   def changeScreen(self,**kwargs):
       self.sm.add_widget(WaitScreen(name='wait'))
       self.sm.current='wait'
if __name__ == '__main__':
   View().run()
```
# エラーが発生しないパターン
- ImageWidget で 画像がない場合(sourceなしや、ファイルがない場合)
- ImageWidget がない場合 (Labelの場合切り替えが可能)
- add_widget(WaitScreen(name='wait'))を、Build内で先に設定
画像を読み込みしようとすると発生するようです。
# 追記1 logLevel=trace
エラー発生前のログです。
```ここに言語を入力
[TRACE ] [Lang       ] Found 2 rules for <Screen name='wait'>
[TRACE ] [Lang       ] Found 1 rules for <kivy.uix.image.Image object at 0x11143c2f0>
[DEBUG ] [ImageImageIO] Load </img/wait1.png>
[TRACE ] [Image      ] u'/img/wait1.png', populate to textures (1)
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6
```
# 追記2 無理やりon_messageで動かした方法
on_message時はフラグ管理だけさせ、Clockでスクリーン変更のフラグチェックをして変更
かなりきな臭いのですがこの場合では想定した動作にはなります。
```ここに言語を入力
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.clock import Clock
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./img/wait1.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   waitflag = False
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
       Clock.schedule_interval(self.changeScreen, 1)
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.waitflag = True
   def changeScreen(self,dt):
       if self.waitflag:
           self.sm.add_widget(WaitScreen(name='wait'))
           self.sm.current='wait'
           self.waitflag = False
if __name__ == '__main__':
   View().run()
```
# 追記3  mqtt(paho.mqtt.client)のコールバック時に発生
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
# 追記4 pygame->SDL2 への変更
回答頂きました内容にpygameからSDL2への推奨がされているということで変更いたしました。
併せてRaspberryPiにも同様のプログラムを走らせました。
(簡単にSDL2に変更できるかと思ったら想像以上に苦戦していまいました。kivy コンパイルし直し・・・)
> https://stackoverflow.com/questions/41819955/how-to-i-get-kivy-1-9-1-or-1-9-2-to-use-sdl2-instead-of-pygame-on-osx-10-12-2
**結果1 RaspberryPiの際は、エラー落ちはしないものの表示されません**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-df7de20, 20180705
[INFO  ] [Python     ] v2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: egl_rpi
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <OpenGL ES 2.0>
[INFO  ] [GL         ] OpenGL vendor <Broadcom>
[INFO  ] [GL         ] OpenGL renderer <VideoCore IV HW>
[INFO  ] [GL         ] OpenGL parsed version: 2, 0
[INFO  ] [GL         ] Shading version <OpenGL ES GLSL ES 1.00>
[INFO  ] [GL         ] Texture max size <2048>
[INFO  ] [GL         ] Texture max units <8>
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
**結果2 MacbookProの際は、エラー発生で落ちました**
ただし内容は、Segmentation fault: 11 になりました。
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-0471549, 20180718
[INFO  ] [Python     ] v2.7.15 (default, Jul 3 2018, 14:22:35)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_imageio, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: sdl2
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <2.1 INTEL-10.34.27>
[INFO  ] [GL         ] OpenGL vendor <Intel Inc.>
[INFO  ] [GL         ] OpenGL renderer <Intel(R) Iris(TM) Graphics 6100>
[INFO  ] [GL         ] OpenGL parsed version: 2, 1
[INFO  ] [GL         ] Shading version <1.20>
[INFO  ] [GL         ] Texture max size <16384>
[INFO  ] [GL         ] Texture max units <16>
[INFO  ] [Window     ] auto add sdl2 input provider
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
以上です。追いかけてみましたが色々と左右される点が多そうですので別の方法を考えてみたいと思います。
もし原因と解決方法がありましたらご教示ください。
# 追記 成功例1 別スレッドをメインスレッドとしてkivy を操作する
今回のエラー・表示がおかしい理由は、回答にあります別スレッドからの動作が原因でした。
OpenGL関連は別スレッドではダメなそうです。
その解決策として以下の方法がありました。
必要な部分は、from kivy.clock import mainthread
メインスレッドで操作させたい別スレッド(ここではon_message)に@mainthreadを前に入れることです。
> https://kivy.org/docs/api-kivy.clock.html
```python
# -*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.lang import Builder
from kivy.clock import mainthread
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait3.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   pass
class View(App):
   def __init__(self, **kwargs):
       global sm
       super(View, self).__init__(**kwargs)
       sm = ScreenManager()
   def build(self):
       sm.switch_to(InitScreen(name='init'))
       return sm
   def on_start(self):
       def on_connect(client, userdata, flags, respons_code):
           cli.subscribe('get/test')
           
       @mainthread
       def on_message(client, userdata, msg):
           print sm.current
           io = msg.payload.decode("utf-8")
           print(msg.topic + ' ' + io)
           if sm.current != io:
               if io == 'wait':
                   sm.switch_to(WaitScreen(name='wait'))
       global cli
       cli = mqtt.Client(protocol=mqtt.MQTTv311)
       cli.on_connect = on_connect
       cli.on_message = on_message
       cli.connect('localhost', port=1883, keepalive=60)
       cli.loop_start()
if __name__ == '__main__':
   View().run()
```
  • Python

    11753 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 2.7

    1457 questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • MQTT

    36 questions

    MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

4 エラー内容追加

BlueBits

BlueBits score 44

2018/07/18 16:03  投稿

kivy + mqtt on_message時の際の表示エラーの解決方法
**Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6 エラーが発生します。**
**原因と、解決策についてご教示いただけますと幸いです。**
**プログラムの目的に沿えば別の方法でも問題ありません**
# プログラムの目的
ScreenManagerにてmqttから通信がきた場合、Screenを切り替える
その際、通信内容からScreenに表示する画像を決める
# 発生内容
** on_messageにて取得後、切り替え操作の際,切り替え後のScreenにImaegeがあると発生する**
以下は発生したエラーを切り分けるため、縮小したプログラムです。
mqttで何かしらきたらScreenを切り替えるだけのものです。
```python
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait1.png'
""")
class Charactor(Image):
   pass
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.changeScreen()
   def changeScreen(self,**kwargs):
       self.sm.add_widget(WaitScreen(name='wait'))
       self.sm.current='wait'
if __name__ == '__main__':
   View().run()
```
# エラーが発生しないパターン
- ImageWidget で 画像がない場合(sourceなしや、ファイルがない場合)
- ImageWidget がない場合 (Labelの場合切り替えが可能)
- add_widget(WaitScreen(name='wait'))を、Build内で先に設定
画像を読み込みしようとすると発生するようです。
# 追記1 logLevel=trace
エラー発生前のログです。
```ここに言語を入力
[TRACE ] [Lang       ] Found 2 rules for <Screen name='wait'>
[TRACE ] [Lang       ] Found 1 rules for <kivy.uix.image.Image object at 0x11143c2f0>
[DEBUG ] [ImageImageIO] Load </img/wait1.png>
[TRACE ] [Image      ] u'/img/wait1.png', populate to textures (1)
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6
```
# 追記2 無理やりon_messageで動かした方法
on_message時はフラグ管理だけさせ、Clockでスクリーン変更のフラグチェックをして変更
かなりきな臭いのですがこの場合では想定した動作にはなります。
```ここに言語を入力
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.clock import Clock
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./img/wait1.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   waitflag = False
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
       Clock.schedule_interval(self.changeScreen, 1)
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.waitflag = True
   def changeScreen(self,dt):
       if self.waitflag:
           self.sm.add_widget(WaitScreen(name='wait'))
           self.sm.current='wait'
           self.waitflag = False
if __name__ == '__main__':
   View().run()
```
# 追記3  mqtt(paho.mqtt.client)のコールバック時に発生
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
# 追記4 pygame->SDL2 への変更
回答頂きました内容にpygameからSDL2への推奨がされているということで変更いたしました。
併せてRaspberryPiにも同様のプログラムを走らせました。
(簡単にSDL2に変更できるかと思ったら想像以上に苦戦していまいました。kivy コンパイルし直し・・・)
> https://stackoverflow.com/questions/41819955/how-to-i-get-kivy-1-9-1-or-1-9-2-to-use-sdl2-instead-of-pygame-on-osx-10-12-2
**結果1 RaspberryPiの際は、エラー落ちはしないものの表示されません**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-df7de20, 20180705
[INFO  ] [Python     ] v2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: egl_rpi
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <OpenGL ES 2.0>
[INFO  ] [GL         ] OpenGL vendor <Broadcom>
[INFO  ] [GL         ] OpenGL renderer <VideoCore IV HW>
[INFO  ] [GL         ] OpenGL parsed version: 2, 0
[INFO  ] [GL         ] Shading version <OpenGL ES GLSL ES 1.00>
[INFO  ] [GL         ] Texture max size <2048>
[INFO  ] [GL         ] Texture max units <8>
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
**結果2 MacbookProの際は、エラー発生で落ちました**
ただし内容は、Segmentation fault: 11 になりました。  
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-0471549, 20180718
[INFO  ] [Python     ] v2.7.15 (default, Jul 3 2018, 14:22:35)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_imageio, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: sdl2
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <2.1 INTEL-10.34.27>
[INFO  ] [GL         ] OpenGL vendor <Intel Inc.>
[INFO  ] [GL         ] OpenGL renderer <Intel(R) Iris(TM) Graphics 6100>
[INFO  ] [GL         ] OpenGL parsed version: 2, 1
[INFO  ] [GL         ] Shading version <1.20>
[INFO  ] [GL         ] Texture max size <16384>
[INFO  ] [GL         ] Texture max units <16>
[INFO  ] [Window     ] auto add sdl2 input provider
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
以上です。追いかけてみましたが色々と左右される点が多そうですので別の方法を考えてみたいと思います。
もし原因と解決方法がありましたらご教示ください。
  • Python

    11753 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 2.7

    1457 questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • MQTT

    36 questions

    MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

3 文章修正

BlueBits

BlueBits score 44

2018/07/18 16:00  投稿

kivy + mqtt on_message時の際の表示エラーの解決方法
**Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6 エラーが発生します。**
**原因と、解決策についてご教示いただけますと幸いです。**
**プログラムの目的に沿えば別の方法でも問題ありません**
# プログラムの目的
ScreenManagerにてmqttから通信がきた場合、Screenを切り替える
その際、通信内容からScreenに表示する画像を決める
# 発生内容
** on_messageにて取得後、切り替え操作の際,切り替え後のScreenにImaegeがあると発生する**
以下は発生したエラーを切り分けるため、縮小したプログラムです。
mqttで何かしらきたらScreenを切り替えるだけのものです。
```python
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait1.png'
""")
class Charactor(Image):
   pass
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.changeScreen()
   def changeScreen(self,**kwargs):
       self.sm.add_widget(WaitScreen(name='wait'))
       self.sm.current='wait'
if __name__ == '__main__':
   View().run()
```
# エラーが発生しないパターン
- ImageWidget で 画像がない場合(sourceなしや、ファイルがない場合)
- ImageWidget がない場合 (Labelの場合切り替えが可能)
- add_widget(WaitScreen(name='wait'))を、Build内で先に設定
画像を読み込みしようとすると発生するようです。
# 追記1 logLevel=trace
エラー発生前のログです。
```ここに言語を入力
[TRACE ] [Lang       ] Found 2 rules for <Screen name='wait'>
[TRACE ] [Lang       ] Found 1 rules for <kivy.uix.image.Image object at 0x11143c2f0>
[DEBUG ] [ImageImageIO] Load </img/wait1.png>
[TRACE ] [Image      ] u'/img/wait1.png', populate to textures (1)
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6
```
# 追記2 無理やりon_messageで動かした方法
on_message時はフラグ管理だけさせ、Clockでスクリーン変更のフラグチェックをして変更
かなりきな臭いのですがこの場合では想定した動作にはなります。
```ここに言語を入力
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.clock import Clock
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./img/wait1.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   waitflag = False
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
       Clock.schedule_interval(self.changeScreen, 1)
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.waitflag = True
   def changeScreen(self,dt):
       if self.waitflag:
           self.sm.add_widget(WaitScreen(name='wait'))
           self.sm.current='wait'
           self.waitflag = False
if __name__ == '__main__':
   View().run()
```
# 追記3  mqtt(paho.mqtt.client)のコールバック時に発生
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
# 追記4 pygame->SDL2 への変更
回答頂きました内容にpygameからSDL2への変更が推奨されているということを調べてみました。
回答頂きました内容にpygameからSDL2への推奨がされているということで変更いたしました。
併せてRaspberryPiにも同様のプログラムを走らせました。
(簡単にSDL2に変更できるかと思ったら想像以上に苦戦していまいました。kivy コンパイルし直し・・・)
> https://stackoverflow.com/questions/41819955/how-to-i-get-kivy-1-9-1-or-1-9-2-to-use-sdl2-instead-of-pygame-on-osx-10-12-2
**結果1 RaspberryPiの際は、エラー落ちはしないものの表示されません**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-df7de20, 20180705
[INFO  ] [Python     ] v2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: egl_rpi
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <OpenGL ES 2.0>
[INFO  ] [GL         ] OpenGL vendor <Broadcom>
[INFO  ] [GL         ] OpenGL renderer <VideoCore IV HW>
[INFO  ] [GL         ] OpenGL parsed version: 2, 0
[INFO  ] [GL         ] Shading version <OpenGL ES GLSL ES 1.00>
[INFO  ] [GL         ] Texture max size <2048>
[INFO  ] [GL         ] Texture max units <8>
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
**結果2 MacbookProの際は、エラー発生で落ちました**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-0471549, 20180718
[INFO  ] [Python     ] v2.7.15 (default, Jul 3 2018, 14:22:35)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_imageio, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: sdl2
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <2.1 INTEL-10.34.27>
[INFO  ] [GL         ] OpenGL vendor <Intel Inc.>
[INFO  ] [GL         ] OpenGL renderer <Intel(R) Iris(TM) Graphics 6100>
[INFO  ] [GL         ] OpenGL parsed version: 2, 1
[INFO  ] [GL         ] Shading version <1.20>
[INFO  ] [GL         ] Texture max size <16384>
[INFO  ] [GL         ] Texture max units <16>
[INFO  ] [Window     ] auto add sdl2 input provider
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
以上です。追いかけてみましたが色々と左右される点が多そうですので別の方法を考えてみたいと思います。
もし原因と解決方法がありましたらご教示ください。
  • Python

    11753 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 2.7

    1457 questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • MQTT

    36 questions

    MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

2 sdl2に変更

BlueBits

BlueBits score 44

2018/07/18 15:59  投稿

kivy + mqtt on_message時の際の表示エラーの解決方法
**Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6 エラーが発生します。**
**原因と、解決策についてご教示いただけますと幸いです。**
**プログラムの目的に沿えば別の方法でも問題ありません**
# プログラムの目的
ScreenManagerにてmqttから通信がきた場合、Screenを切り替える
その際、通信内容からScreenに表示する画像を決める
# 発生内容
** on_messageにて取得後、切り替え操作の際,切り替え後のScreenにImaegeがあると発生する**
以下は発生したエラーを切り分けるため、縮小したプログラムです。
mqttで何かしらきたらScreenを切り替えるだけのものです。
```python
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait1.png'
""")
class Charactor(Image):
   pass
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.changeScreen()
   def changeScreen(self,**kwargs):
       self.sm.add_widget(WaitScreen(name='wait'))
       self.sm.current='wait'
if __name__ == '__main__':
   View().run()
```
# エラーが発生しないパターン
- ImageWidget で 画像がない場合(sourceなしや、ファイルがない場合)
- ImageWidget がない場合 (Labelの場合切り替えが可能)
- add_widget(WaitScreen(name='wait'))を、Build内で先に設定
画像を読み込みしようとすると発生するようです。
# 追記1 logLevel=trace
エラー発生前のログです。
```ここに言語を入力
[TRACE ] [Lang       ] Found 2 rules for <Screen name='wait'>
[TRACE ] [Lang       ] Found 1 rules for <kivy.uix.image.Image object at 0x11143c2f0>
[DEBUG ] [ImageImageIO] Load </img/wait1.png>
[TRACE ] [Image      ] u'/img/wait1.png', populate to textures (1)
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6
```
# 追記2 無理やりon_messageで動かした方法
on_message時はフラグ管理だけさせ、Clockでスクリーン変更のフラグチェックをして変更
かなりきな臭いのですがこの場合では想定した動作にはなります。
```ここに言語を入力
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.clock import Clock
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./img/wait1.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   waitflag = False
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
       Clock.schedule_interval(self.changeScreen, 1)
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.waitflag = True
   def changeScreen(self,dt):
       if self.waitflag:
           self.sm.add_widget(WaitScreen(name='wait'))
           self.sm.current='wait'
           self.waitflag = False
if __name__ == '__main__':
   View().run()
```
# 追記3  mqtt(paho.mqtt.client)のコールバック時に発生
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
# 追記4 pygame->SDL2 への変更
回答頂きました内容にpygameからSDL2への変更が推奨されているということを調べてみました。
(簡単にSDL2に変更できるかと思ったら想像以上に苦戦していまいました。kivy コンパイルし直し・・・)
> https://stackoverflow.com/questions/41819955/how-to-i-get-kivy-1-9-1-or-1-9-2-to-use-sdl2-instead-of-pygame-on-osx-10-12-2
**結果1 RaspberryPiの際は、エラー落ちはしないものの表示されません**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-df7de20, 20180705
[INFO  ] [Python     ] v2.7.13 (default, Nov 24 2017, 17:33:09)
[GCC 6.3.0 20170516]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: egl_rpi
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <OpenGL ES 2.0>
[INFO  ] [GL         ] OpenGL vendor <Broadcom>
[INFO  ] [GL         ] OpenGL renderer <VideoCore IV HW>
[INFO  ] [GL         ] OpenGL parsed version: 2, 0
[INFO  ] [GL         ] Shading version <OpenGL ES GLSL ES 1.00>
[INFO  ] [GL         ] Texture max size <2048>
[INFO  ] [GL         ] Texture max units <8>
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
**結果2 MacbookProの際は、エラー発生で落ちました**
```ここに言語を入力
[INFO  ] [Kivy       ] v1.11.0.dev0, git-0471549, 20180718
[INFO  ] [Python     ] v2.7.15 (default, Jul 3 2018, 14:22:35)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
[INFO  ] [Factory    ] 194 symbols loaded
[INFO  ] [Image      ] Providers: img_tex, img_imageio, img_dds, img_sdl2, img_gif (img_pil, img_ffpyplayer ignored)
[INFO  ] [Window     ] Provider: sdl2
[INFO  ] [GL         ] Using the "OpenGL ES 2" graphics system
[INFO  ] [GL         ] Backend used <gl>
[INFO  ] [GL         ] OpenGL version <2.1 INTEL-10.34.27>
[INFO  ] [GL         ] OpenGL vendor <Intel Inc.>
[INFO  ] [GL         ] OpenGL renderer <Intel(R) Iris(TM) Graphics 6100>
[INFO  ] [GL         ] OpenGL parsed version: 2, 1
[INFO  ] [GL         ] Shading version <1.20>
[INFO  ] [GL         ] Texture max size <16384>
[INFO  ] [GL         ] Texture max units <16>
[INFO  ] [Window     ] auto add sdl2 input provider
[INFO  ] [Window     ] virtual keyboard not allowed, single mode, not docked
[INFO  ] [Text       ] Provider: sdl2
[INFO  ] [Base       ] Start application main loop
[INFO  ] [GL         ] NPOT texture support is available
```
以上です。追いかけてみましたが色々と左右される点が多そうですので別の方法を考えてみたいと思います。
もし原因と解決方法がありましたらご教示ください。
  • Python

    11753 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 2.7

    1457 questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • MQTT

    36 questions

    MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

1 追記1〜3を追加

BlueBits

BlueBits score 44

2018/07/18 09:46  投稿

kivy + mqtt on_message時の際の表示エラーの解決方法
**Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6 エラーが発生します。**
**原因と、解決策についてご教示いただけますと幸いです。**
**プログラムの目的に沿えば別の方法でも問題ありません**  
# プログラムの目的
ScreenManagerにてmqttから通信がきた場合、Screenを切り替える
その際、通信内容からScreenに表示する画像を決める
# 発生内容
** on_messageにて取得後、切り替え操作の際,切り替え後のScreenにImaegeがあると発生する**
以下は発生したエラーを切り分けるため、縮小したプログラムです。
mqttで何かしらきたらScreenを切り替えるだけのものです。
```python
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./wait1.png'
""")
class Charactor(Image):
   pass
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.changeScreen()
   def changeScreen(self,**kwargs):
       self.sm.add_widget(WaitScreen(name='wait'))
       self.sm.current='wait'
if __name__ == '__main__':
   View().run()
```
# エラーが発生しないパターン
- ImageWidget で 画像がない場合(sourceなしや、ファイルがない場合)
- ImageWidget がない場合 (Labelの場合切り替えが可能)
- add_widget(WaitScreen(name='wait'))を、Build内で先に設定
画像を読み込みしようとすると発生するようです。
画像を読み込みしようとすると発生するようです。
# 追記1 logLevel=trace
エラー発生前のログです。
```ここに言語を入力
[TRACE ] [Lang       ] Found 2 rules for <Screen name='wait'>
[TRACE ] [Lang       ] Found 1 rules for <kivy.uix.image.Image object at 0x11143c2f0>
[DEBUG ] [ImageImageIO] Load </img/wait1.png>
[TRACE ] [Image      ] u'/img/wait1.png', populate to textures (1)
Fatal Python error: (pygame parachute) Segmentation Fault
Abort trap: 6
```
# 追記2 無理やりon_messageで動かした方法
on_message時はフラグ管理だけさせ、Clockでスクリーン変更のフラグチェックをして変更
かなりきな臭いのですがこの場合では想定した動作にはなります。
```ここに言語を入力
#-*- coding: utf-8 -*-
import paho.mqtt.client as mqtt
from kivy.app import App
from kivy.uix.screenmanager import ScreenManager, Screen
from kivy.uix.image import Image
from kivy.lang import Builder
from kivy.clock import Clock
Builder.load_string("""
<InitScreen>:
   AnchorLayout:
       anchor_x:"center"
       anchor_y:"center"
       Label:
           text:"init"
<WaitScreen>:
   Image:
       id:charactor
       pos_hint:{'center_x':.5,'y':0 }
       size_hint:1,1
       source:'./img/wait1.png'
""")
class InitScreen(Screen):
   pass
class WaitScreen(Screen):
   def __init__(self, **kwargs):
       super(WaitScreen, self).__init__(**kwargs)
class View(App):
   sm = ScreenManager()
   cli = mqtt.Client(protocol=mqtt.MQTTv311)
   waitflag = False
   def __init__(self, **kwargs):
       super(View, self).__init__(**kwargs)
   def build(self):
       self.sm.add_widget(InitScreen(name='init'))
       self.sm.current='init'
       return self.sm
   def on_start(self):
       self.cli.on_connect = self.on_connect
       self.cli.on_message = self.on_message
       self.cli.connect('localhost', port='1883', keepalive=60)
       self.cli.loop_start()
       Clock.schedule_interval(self.changeScreen, 1)
   def on_connect(self,client, userdata, flags, respons_code):
       print('status {0}'.format(respons_code))
       client.subscribe('get/test')
   def on_message(self,client, userdata, msg):
       self.waitflag = True
   def changeScreen(self,dt):
       if self.waitflag:
           self.sm.add_widget(WaitScreen(name='wait'))
           self.sm.current='wait'
           self.waitflag = False
if __name__ == '__main__':
   View().run()
```
# 追記3  mqtt(paho.mqtt.client)のコールバック時に発生
コールバックに使用しているon_message(on_connect)のself.changeScreen()を実行するとエラーが質問のエラーが発生します。on_start時は成功しました。
  • Python

    11753 questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

  • Python 2.7

    1457 questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

  • MQTT

    36 questions

    MQTT(Message Queue Telemetry Transport)とは、TCP/IPネットワークで利用可能な通信プロトコルの一つで、IoT/M2M向けに開発された軽量なプロトコルです。ヘッダ部分は最小2バイトと小さく、通信量・CPU負荷・電力消費量などを抑えることができます。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る