Python Forum
[WxPython] Which def is executed?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[WxPython] Which def is executed?
#1
# -*- coding: cp1252 -*-

import wx

zd = Zeigedict = {"zeigspalten": ["A", "B"], "zeigreihen": ["a", "b"]}

class Mainframe(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

        self.dpbox = dpbox = wx.BoxSizer(wx.HORIZONTAL) 
        self.SetSizer(dpbox)

        # # # Teil 2: Menubalken        
        menuBar = wx.MenuBar()

        setzenMenu = wx.Menu()
        sid = wx.ID_ANY
        setzenMenu.Append(sid, "Spalten", "Spaltengruppen setzen")
        wx.EVT_MENU(self, sid, self.OnZeigspalten)
        rid = wx.ID_ANY
        setzenMenu.Append(rid, "Reihen", "Reihengruppen setzen")
        wx.EVT_MENU(self, rid, self.OnZeigreihen)

        menuBar.Append(setzenMenu, "Setzen")
        self.SetMenuBar(menuBar)

        self.Show()
        

    def OnZeigspalten(self, event):
        self.spalcmbb = spalcmbb = wx.MultiChoiceDialog(self, 
                                   "Spaltenauswahl nach Gruppen",
                                   "Spaltenauswahl nach Gruppen",
                                    zd["zeigspalten"])

        if (spalcmbb.ShowModal() == wx.ID_OK):
            spaltenwahl = spalcmbb.GetSelections()
            print "gewählt sind Spalten: ", spaltenwahl
            print "-> ",
            for sw in spaltenwahl:
                print zd["zeigspalten"][sw], ", ",
            print  


        spalcmbb.Destroy()
        return
        
    def OnZeigreihen(self, event):
        self.reihcmbb = reihcmbb = wx.MultiChoiceDialog(self, 
                                   "Reihenauswahl nach Gruppen",
                                   "Reihenauswahl nach Gruppen",
                                    zd["zeigreihen"])

        if (reihcmbb.ShowModal() == wx.ID_OK):
            reihenwahl = reihcmbb.GetSelections()
            print "gewählt sind Reihen: ", reihenwahl


        reihcmbb.Destroy()
        return

if __name__ == "__main__": 

    app = wx.App(0)
    preframe = Mainframe(None, -1, "Anfangsauswahl")   
    app.MainLoop() 
If I run this and choose "Spalten" from the menu, it seems that OnZeigreihen is executed and not OnZeigspalten. Why?
Reply
#2
It's right at the bottom of the __init__ method.
self.Show()
but you don't show that code.
Reply
#3
Why not?
self.SetMenuBar(menuBar)
is the same self, isn't it?

And if I didn't, why is one of the defs executed at all? It's just not the *right* one.
Reply
#4
looking closer, (since you don't supply a traceback which would be most helpful)
I would expect an error (I would expect fatal) when the show() statement is encountered
because there is no show() method. But if not, the menu is dependent on the value of rid and sid
at the time of code compilation, not at run time, so also will not give expected results.
Reply
#5
A Traceback? From where could I get that?
There is no error. Everything looks fine... except that in the case of the both shown defs, the one is exectued instead of the other.

I can add other menu items, they are okay. Only those both mix up.

Edit:
It'S the same without sid and rid. They were a 'remainder' of my attempts to find an access to the problem.

# -*- coding: cp1252 -*-

import wx

zd = Zeigedict = {"zeigspalten": ["A", "B"], "zeigreihen": ["a", "b"]}

class Mainframe(wx.Frame):
    def __init__(self, parent, id, title):
        wx.Frame.__init__(self, parent, id, title)

        self.dpbox = dpbox = wx.BoxSizer(wx.HORIZONTAL) 
        self.SetSizer(dpbox)

        # # # Teil 2: Menubalken        
        menuBar = wx.MenuBar()

        setzenMenu = wx.Menu()
        setzenMenu.Append(wx.ID_ANY, "Spalten", "Spaltengruppen setzen")
        wx.EVT_MENU(self, wx.ID_ANY, self.OnZeigspalten)
        setzenMenu.Append(wx.ID_ANY, "Reihen", "Reihengruppen setzen")
        wx.EVT_MENU(self, wx.ID_ANY, self.OnZeigreihen)

        menuBar.Append(setzenMenu, "Setzen")
        self.SetMenuBar(menuBar)

        self.Show()
        

    def OnZeigspalten(self, event):
        self.spalcmbb = spalcmbb = wx.MultiChoiceDialog(self, 
                                   "Spaltenauswahl nach Gruppen",
                                   "Spaltenauswahl nach Gruppen",
                                    zd["zeigspalten"])

        if (spalcmbb.ShowModal() == wx.ID_OK):
            spaltenwahl = spalcmbb.GetSelections()
            print "gewählt sind Spalten: ", spaltenwahl
            print "-> ",
            for sw in spaltenwahl:
                print zd["zeigspalten"][sw], ", ",
            print  


        spalcmbb.Destroy()
        return
        
    def OnZeigreihen(self, event):
        self.reihcmbb = reihcmbb = wx.MultiChoiceDialog(self, 
                                   "Reihenauswahl nach Gruppen",
                                   "Reihenauswahl nach Gruppen",
                                    zd["zeigreihen"])

        if (reihcmbb.ShowModal() == wx.ID_OK):
            reihenwahl = reihcmbb.GetSelections()
            print "gewählt sind Reihen: ", reihenwahl


        reihcmbb.Destroy()
        return

if __name__ == "__main__": 

    app = wx.App(0)
    preframe = Mainframe(None, -1, "Anfangsauswahl")   
    app.MainLoop() 
Reply
#6
traceback is what python prints out on the console when an error is encountered

Your code has changed, "sid = wx.ID_ANY" is no longer there, but in the menu definition.
This does not change the issue, which is:
The reason is that the initial value of wx.ID_ANY ire compiled into the menu
like a constant, not a variable. So it's permanent value is what it was when the
menu code was first encountered on initialization. The actual value of wx.ID_ANY can change,
but the menu value remains constant. You need to query that value at the time the menu
method is executed.
Reply
#7
How can I get the traceback then if it's not given by itself - to provide it here as you demanded?

And how can I query the value for the menu? I have never seen any code that does so, so I have simply no idea (and I wonder why this is necessary in this one case as it is never anywhere else; all other menu items work fine without). As usual, the wxpython docs don't give any hint (at least none that I could find).
Reply
#8
OK, you've got me second guessing myself.
give me a few minutes to try some stuff

can't stand working in python2.7, and unable to install wx.
I think you'll have to wait for someone else to continue here

Not sure anymore about what I was leading to with the class init,
and I'm second guessing as to the validity of what I originally thought to be the ase anyway
Reply
#9
All you need to change in the first code to make it work is
change
setzenMenu.Append(sid, "Spalten", "Spaltengruppen setzen")
wx.EVT_MENU(self, sid, self.OnZeigspalten)
to
menu_spalten = setzenMenu.Append(sid, "Spalten", "Spaltengruppen setzen")
self.Bind(wx.EVT_MENU, self.OnZeigspalten, menu_spalten)
and change
setzenMenu.Append(rid, "Reihen", "Reihengruppen setzen")
wx.EVT_MENU(self, rid, self.OnZeigreihen)
to
menu_reihen = setzenMenu.Append(rid, "Reihen", "Reihengruppen setzen")
self.Bind(wx.EVT_MENU, self.OnZeigreihen, menu_reihen)
Reply
#10
Thanks to both of you!
I can't say that I understand what's happening with the IDs, but it works.

It guess that I was led into this trap by the "Style Guide" from https://wiki.wxpython.org/wxPython%20Style%20Guide. It's more or less the only site where I could find something about the usage of ids in wxpython at all. There, it's written:
Quote:Don't use IDs. There is very rarely a good reason to use them.
...
If the id is a required argument, use wx.ID_ANY.
...
EXCEPTION: (there's always an exception!) Use standard IDs for standard menus, buttons, etc. It is useful to use the standard IDs because they may turn on standard functionality, such as menu item remapping for wxMac, automatic Dialog completion or cancellation, using stock button labels and images, etc.  
...
By using your own ids you just block this ability to play by the rules.

If I use the menu build-up pattern I had in the beginnig, the id seems to be a 'required argument'. Unfortunately, the guide only writes something about the standard menus, but nothing is mentioned for other (own) menu items. So, I did what it writes - I used wx.ID_ANY. I have seen that other people use 'fixed' ids in that case, but I rated the style guide higher. I assume that there is a secret list of 'fixed' ids, and I would prefer to avoid collisions that may lead to hard-to-detect misfunctions if I accidentally hit a predefined id.

And if I understand, Yoritz' code allows to circumvent this by naming the object that is created by the 'Append' and used the id that is 'packed' into it, therefore no more being an (explicit) 'required argument'.


Well, now I wonder more that most of the code was working well, and the misfunction was completely reproducable. I would have guessed that in the case of an assignment of 'random' ids there would be a more 'random' behaviour, too.

And: Does someone know a place where one can learn more about the secrets of ids in wxpython? I searched the docs, but the seem to write nothing at all about ids.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  [Tkinter] messagebox is not being executed please help erwinsiuda 2 2,240 Apr-02-2020, 01:56 AM
Last Post: Larz60+
  [Tkinter] Window unresponsive when executed. fawazcode 2 3,749 Sep-11-2017, 12:29 AM
Last Post: Larz60+
  [xbmc] How to block the code from executed twice under the loop chris0147 29 22,760 Oct-26-2016, 05:34 PM
Last Post: nilamo

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020