これは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'
http://stackoverflow.com/help/mcve – EL3PHANTEN
あなたのコメントのポイントは何ですか?私はこの質問を作成したときにあなたのリンクのガイドに従った。それは完全であり、最小であり、検証可能である。 –
ポイントは、あなたのポップアップの最小限の例を作るのに4つのファイルは必要ありません。スレッドとキューのようなコードには、無関係なものがたくさんあります。エラーを再現するには、単純なPopupが必要です。 – EL3PHANTEN