BruceSherwood / vpython-wx

VPython based on wxPython
Other
70 stars 38 forks source link

Strange bug with opacity and wxPython #74

Closed dorverbin closed 9 years ago

dorverbin commented 9 years ago

Below is a pretty simple code, initializing a wxPython window with a VPython display. At first, a box with opacity 0.5 is created, along with a button. When the button is clicked, a second box with the same opacity is created, but after its opacity has been changed, its frame is chosen to be a new frame, f2. When the second box is moved, the first box disappears.

On the other hand, if we initially create the second box with b2 = v.box(frame=f2), and remove the line where we change b2's frame, this bug does not occur. If we remove the part where you have to click a button, but instead everything happens consecutively, this bug also does not occur.

Any idea why is that?

import visual as v
import wx

class MainWindow():
    def __init__(self):
        window = v.window(width=300, height=400, title='VPython Bug')
        window.win.Center()
        v.display(window=window, width=300, height=300)

        v.box(opacity=0.5)

        wx.Button(window.panel, 1, 'Click Me', size=(100, 30), pos=(100, 320))

        def on_button(event):
            f2 = v.frame()
            b2 = v.box()
            b2.opacity = 0.5
            b2.frame = f2
            b2.x = 2

        window.win.Bind(wx.EVT_BUTTON, on_button, id=1)

def main():
    MainWindow()
    while True:
        v.rate(1)

if __name__ == '__main__':
    main()
BruceSherwood commented 9 years ago

Below I show an altered version of the code, as I struggled to understand what was to be indented without the program being wrapped in triple backslanted single quotes. I hope that this captures the original; in particular, I couldn't understand how "window" was recognized, hence self.window.

I think the simple answer is that setting the frame of an object after creating the object will almost certainly lead to all kinds of unpredictable behavior.

A minor point: There is no need to end a VPython program with while True: v.rate(1), as this is automatically present at the end of a VPython program.

import visual as v
import wx

class MainWindow():
    def __init__(self):
        self.window = v.window(width=300, height=400, title='VPython Bug')
        self.window.win.Center()
        v.display(window=self.window, width=300, height=300)
        v.box(color=v.color.red, opacity=0.5)
        wx.Button(self.window.panel, 1, 'Click Me', size=(100, 30), pos=(100, 320))

def on_button(event):
    f2 = v.frame(pos=(-4,2,0))
    b2 = v.box(frame=f2, color=v.color.cyan)
    b2.opacity = 0.5
    b2.x = 2

def main():
    m = MainWindow()
    m.window.win.Bind(wx.EVT_BUTTON, on_button, id=1)

main()
dorverbin commented 9 years ago

Thank you very much for the quick answer!

About the indentation issue - I simply defined "on_button" as a closure - a function defined within a function's scope to be used only locally, so the indentation was as is. Your code seems equivalent though, and should have the same problem before you fixed it by defining the frame when calling v.box().

So from what you're saying I understand that I should always define the object's frame when making it. I never saw any reference to that on the documentation before, I believe, but I will do so. Are there any other properties that need to be set when making an object, or just the frame?

Thank you.

BruceSherwood commented 9 years ago

I think frame is the only example of this.