2016-12-06 23 views
0

これはKivyの以前のバージョンについて尋ねられた質問に似ています:Kivy Popup rendering issue しかし有用な答えは見つかりませんでした。Windows 10でkivyポップアップが失敗する

これは、Kivy 1.9.1とPython 2.7.12を使用してWindows 10でPopupを使用した場合に発生する問題を簡略化したものです。ポップアップが開かれるたびに問題は表示されませんが、時間の約50%が発生します。ポップアップのレイアウトが間違っていることや時には間違っていることがある(つまり、ボタンのテキストやポップアップ内のタイトルでもないボタンテキストなど)。私はポップアップが完了するのを待つためにスレッドとキューを使用しています。問題を確認するには、kivyplay.pyスクリプトを実行し、「Start Game Thread」をクリックします。ポップアップで「OK」ボタンをクリックします。ポップアップは4回表示され、問題が表示されない場合は、「ゲームスレッドの開始」をもう一度クリックできます。表示される警告メッセージは次のとおりです。

[WARNING   ] <kivy.uix.gridlayout.GridLayout object at 0x000000000ADDF118> have no cols or rows set, layout is not triggered. 

私はGridLayoutウィジェットを直接使用していません。この同じコードは、KivyとPythonの同じバージョンで、Ubuntu 16.04の下で完璧に動作し、警告なしで動作します。

私は、多くの異なるアプローチを試してみました。代わりに、キューのスレッドロックを使用して

  • はMyPopupでポップアップを作成するのではなくMyPopupでModalViewを作成するのではなく
  • 排除をサブクラス
  • をサブクラス化pop_test.kvは完全にポップアップコンテンツとしてButtonを使用します。

ModalViewを使用すると、GridLayoutの警告は消えますが、問題は解決されません。ポップアップのレイアウトが複雑になればなるほど、エラーが頻繁に表示されるように見えるので、この単純な例ではエラーがかなり頻繁に表示されることはありません。私は何か間違っているのですか?ポップアップを正しくレンダリングする方法に関するアイデアはありますか?私はこれをバグとして報告すべきでしょうか?

ありがとうございました!

kivyplay.kv:

from kivy.app import App 
from kivy.uix.relativelayout import RelativeLayout 

from game_thread import GameThread 

class KivyPlay(RelativeLayout): 

    def __init__(self, *args): 
     RelativeLayout.__init__(self, *args) 

    def start_thread(self): 
     print "Got a click" 
     gameThread = GameThread() 
     gameThread.start() 

    def quit(self): 
     app.stop() 

class PlayApp(App): 
    def build(self): 
     return KivyPlay() 

if __name__ == '__main__': 
    app = PlayApp() 
    app.run() 

game_thread.py:

from threading import * 
from Queue import Queue 

from my_popup import MyPopup 

class GameThread(Thread): 

    def __init__(self): 
     Thread.__init__(self, name="GameThread") 
     self.daemon = True 
     self.queue = Queue() 


    def run(self): 

     for i in range(0,4): 
      popup = MyPopup("Popup Test", self.queue, i) 
      popup.open() 
      popReturn = self.queue.get(True) 
      print "Popup #" + str(i) + " returned " + str(popReturn) 

my_popup.ky:

from kivy.uix.popup import Popup 
from kivy.lang import Builder 

class MyPopup(Popup): 

    def __init__(self, theTitle, theQueue, playerNumber): 
     self.queue = theQueue 
     title = theTitle 
     self.player = playerNumber 
     myContent = Builder.load_file('pop_test.kv') 
     self.button = myContent.ids["ok_button"] 
     self.button.bind(on_press=self.okButton) 
     Popup.__init__(self, title=title, title_align='center', content=myContent, size_hint=(None, None), size=(400,150), auto_dismiss=False) 

    def okButton(self, *args): 
     self.queue.put(self.player, False) 
     self.dismiss() 

play.kv:

#:kivy 1.9.1 

<KivyPlay>: 
    canvas: 
     Color: 
      rgba: 1, 0, 0, 1 
     Rectangle: 
      pos: self.pos 
      size: self.size 
    Button: 
     size_hint: 0.25, 0.25 
     pos_hint: {'center_x': 0.5, 'y': 0.5} 
     text: 'Start Game Thread' 
     on_press: root.start_thread() 

    Button: 
     size_hint: 0.25, 0.25 
     pos_hint: {'center_x': 0.5, 'y': 0.25} 
     text: 'Quit' 
     on_press: root.quit() 

pop_test.kv:

#:kivy 1.9.1 

BoxLayout: 
    orientation: 'vertical' 

    AnchorLayout: 
     anchor_x: 'center' 
     anchor_y: 'center' 
     Button: 
      id: ok_button 
      size_hint: 0.2, 0.2 
      text: 'OK' 
+1

http://stackoverflow.com/help/mcve – EL3PHANTEN

+0

あなたのコメントのポイントは何ですか?私はこの質問を作成したときにあなたのリンクのガイドに従った。それは完全であり、最小であり、検証可能である。 –

+0

ポイントは、あなたのポップアップの最小限の例を作るのに4つのファイルは必要ありません。スレッドとキューのようなコードには、無関係なものがたくさんあります。エラーを再現するには、単純なPopupが必要です。 – EL3PHANTEN

答えて

0

あなたは__init__の実行時にクラスでoveridingものを開始する前に、あなたがウィジェットを開始することを確認するために、上部にsuper()を呼び出す必要があります。

私は3つのファイルを変更しました。そして、私はどんなエラーも見ません(勝利10でテストされます)。グリッドレイアウト警告を無視することができます。

kivy_play。PY:

from kivy.app import App 
from kivy.uix.relativelayout import RelativeLayout 

from game_thread import GameThread 

class KivyPlay(RelativeLayout): 

    def __init__(self, **kwargs): 
     super(KivyPlay,self).__init__(**kwargs) 

    def start_thread(self): 
     print "Got a click" 
     gameThread = GameThread() 
     gameThread.start() 

    def quit(self): 
     app.stop() 

class PlayApp(App): 
    def build(self): 
     return KivyPlay() 

if __name__ == '__main__': 
    app = PlayApp() 
    app.run() 

そしてmy_popup.py:

from kivy.uix.popup import Popup 
from kivy.lang import Builder 

Builder.load_file('pop_test.kv') 

class MyPopup(Popup): 

    def __init__(self, theTitle, theQueue, playerNumber,**kwargs): 
     super(MyPopup,self).__init__(**kwargs) 
     self.title = theTitle 
     self.title_align='center' 
     self.queue = theQueue 
     self.player = playerNumber 
     self.size_hint=(None, None) 
     self.size=(400,150) 
     self.auto_dismiss=False 


    def okButton(self, *args): 
     self.queue.put(self.player, False) 
     self.dismiss() 

pop_test.kv:

#:kivy 1.9.1 

<MyPopup>: 
    BoxLayout: 
     orientation: 'vertical' 

     AnchorLayout: 
      anchor_x: 'center' 
      anchor_y: 'center' 
      Button: 
       id: ok_button 
       size_hint: 0.2, 0.2 
       text: 'OK' 
       on_press:root.okButton() 
+0

ご協力ありがとうございますが、問題は解決されませんでした。私は時々悪いレイアウトを見ます。おそらく私の最初の50%の見積もりはやや高かったかもしれませんが、Windows 10でそれを実行しようとする顧客に私のコードを提供しないことがしばしばあります。私はkivyの開発版(v1。 9.2-dev0)、それは違いはありませんでした。 –

+0

@JohnAnderson大丈夫、私はそれを複数回実行しようとします。たぶん私は何かを見つけます。 – EL3PHANTEN

+0

誤ってレンダリングされたポップアップの画像をキャプチャすることにしました。 Widget.export_to_png()またはWindow.screenshot()を使用しようとしても失敗していました。そこで、私は画像を取得するためにサブプロセスを使用しました。コードは上記とは少し異なりますが、ここに期待される結果があります:![correct](https://www.dropbox.com/s/na0ljxgaxi6a4g6/correct..png?dl=0)ここには典型的なエラーがあります:![エラー](https://www.dropbox.com/s/l3vgunke8mdkptw/error2.png?dl=0)これらの画像リンクを正しく行ったかどうかはわかりません。私はこの問題がNVIDIAドライバに関係する可能性があると疑っています。 –

関連する問題