2016-12-06 92 views
0

这与提问Kivy早期版本的问题类似:Kivy Popup rendering issue 但是没有找到有用的答案。在Windows 10下,kivy Popup失败

这是一个简化版本的问题,我在基于Kivy 1.9.1和Python 2.7.12的Windows 10下使用Popup。这个问题并不是每次打开Popup时都会出现,但大约有50%的时间发生。症状是Popup的布局有时是不正确的,有时是非常不正确的(即,按钮文本甚至不在按钮上,或者标题甚至不在弹出框内)。我正在使用线程和队列来等待弹出窗口完成。要查看问题,请运行kivyplay.py脚本,单击“启动游戏线程”,单击弹出框中的“确定”按钮。 Popup将出现4次,如果问题没有出现,您可以再次单击“开始游戏线程”。我看到的警告消息是:

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

我没有直接使用任何GridLayout小部件。这个相同的代码完美无缺地工作,没有在Ubuntu 16.04下使用相同版本的Kivy和Python发出警告。

我已经试过许多不同的方法:

  • 使用,而不是一个队列
  • 创建于MyPopup一个弹出,而不是继承
  • 创建于MyPopup一个ModalView而不是继承
  • 消除线程锁pop_test.kv完全只用一个Button作为Popup内容

使用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()

所以我更改了三个文件。我没有看到任何错误(在胜利10测试)。您可以忽略网格布局警告。

kivy_play。潘岳:

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()。所以我最终使用一个子进程来获取图像。代码与上面有点不同,但这里是预期的结果:![正确](https://www.dropbox.com/s/na0ljxgaxi6a4g6/correct..png?dl=0),这里是一个典型的错误:![error](https://www.dropbox.com/s/l3vgunke8mdkptw/error2.png?dl=0)不知道我是否正确地做了这些图片链接。我怀疑这个问题可能与NVIDIA驱动程序有关。 –