У меня проблема с моим меню в WxPython! В заголовке файла у меня есть «Файл», и у меня есть 2 варианта: «Сохранить» и «Закрыть» ... Когда я нажимаю «Сохранить», я хочу, чтобы он печатал «Сохранено», и когда я закрываю часы, приложение должно печатать «Закрыто» и закрыто... Но если я нажму даже сохранить, оно закрывается! Пожалуйста, помогите мне. Вот часть моего кода:
menubar = wx.MenuBar()
fileMenu = wx.Menu()
menubar.Append ( fileMenu, '&File' )
m1 = fileMenu.Append ( wx.ID_EXIT, 'Save' )
self.Bind ( wx.EVT_MENU, self.OnSave, m1 )
m2 = fileMenu.Append ( wx.ID_EXIT, 'Quit' )
self.Bind ( wx.EVT_MENU, self.OnQuit, m2 )
self.SetMenuBar ( menubar )
И функции:
def OnSave ( self, event ):
text = self.text_ctrl.GetValue()
fil.write ( text )
print ( "Saved file")
def OnQuit ( self, event ):
print ( "Closed" )
self.Close()
Первый параметр fileMenu.Append важен. Он используется, чтобы отличить один пункт меню от другого, но вы использовали одно и то же значение для обоих.
m1 = fileMenu.Append(wx.ID_SAVE, 'Save')
self.Bind(wx.EVT_MENU, self.OnSave, m1)
m2 = fileMenu.Append(wx.ID_EXIT, 'Quit')
self.Bind(wx.EVT_MENU, self.OnQuit, m2)
В своих программах я предпочитаю получать бесплатный идентификатор из системы, используя wx.NewId(). Если у вас есть эти «стандартные» пункты меню, ID_SAVE и ID_EXIT имеют смысл, но если вы делаете свои собственные записи, вы можете сделать:
m3 = fileMenu.Append(wx.NewId(), 'My own menu item')
self.Bind(wx.EVT_MENU, self.OnMyOwnFunction, m3)
m4 = fileMenu.Append (wx.NewId(), 'Another menu item')
self.Bind(wx.EVT_MENU, self.OnAnotherFunction, m4)
Вы используете одно и то же Id
, то есть wx.ID_EXIT
для обоих пунктов меню, что, как указал @Petr Blahos, вызывает вашу проблему.
Однако есть проблема с ответом Петра, хотя он технически правильный,wx.NewId
теперь Deprecated
, и хотя он все еще работает, его заменили на wx.NewIdRef
.
wx.NewId()
Generates an integer identifier unique to this run of the program.
Return type
int
Deprecated IDs generated by this function can possibly conflict with IDs used elsewhere in the application code. It is recommended to instead use the wx.ID_ANY ID to assign generated IDs for the controls, menu items and etc. that you create in the application. These IDs are guaranteed to not conflict with the other IDs that are in use in the application. For those cases where you need to create an ID that can be used more than once then please see wx.NewIdRef.
wx.NewIdRef(count=1)
Reserves a new Window ID (or range of WindowIDs) and returns a wx.WindowIDRef object (or list of them) that will help manage the reservation of that ID.
This function is intended to be a drop-in replacement of the old and deprecated wx.NewId function, with the added benefit that the ID should never conflict with an in-use ID or other IDs generated by this function.
wx.NewIdRef
также имеет функцию count
, поэтому ее можно использовать для grab
группы идентификаторов, которые вы используете по мере необходимости. то есть
>>> myIds = wx.NewIdRef(count=6)
>>> myIds
[WindowIDRef: -31973, WindowIDRef: -31972, WindowIDRef: -31971, WindowIDRef: -31970, WindowIDRef: -31969, WindowIDRef: -31968]
>>> useId = myIds[3].Id
>>> useId
-31970
Обратите внимание, что в этом контексте меню можно использовать wx.NewIdRef
, wx.ID_ANY
и -1
. Посмотрите этот простой пример:
import wx
class Test(wx.Frame):
def __init__(self,parent):
wx.Frame.__init__(self,parent,title = "Frame aka Window",size = (300,200))
panel = wx.Panel(self)
self.status=self.CreateStatusBar()
self.status.SetStatusText("Status bar text")
menubar=wx.MenuBar()
firstm=wx.Menu()
secondm=wx.Menu()
fm1 = wx.MenuItem(firstm, wx.NewIdRef(), 'New Window\tAlt+N')
firstm.Append(fm1)
self.Bind(wx.EVT_MENU, self.OnMenu1, id=fm1.GetId())
fm2 = wx.MenuItem(firstm, wx.NewIdRef(), 'Open', "Text for the statusbar")
firstm.Append(fm2)
self.Bind(wx.EVT_MENU, self.OnMenu2, id=fm2.GetId())
fm3 = wx.MenuItem(firstm, -1, 'Quit\tAlt+Q')
firstm.Append(fm3)
self.Bind(wx.EVT_MENU, self.OnMenu3, id=fm3.GetId())
sm1 = wx.MenuItem(firstm, wx.ID_ANY, 'Re-Do', "Statusbar Re-Do")
secondm.Append(sm1)
self.Bind(wx.EVT_MENU, self.OnsMenu1, id=sm1.GetId())
sm2 = wx.MenuItem(secondm, wx.ID_ANY, 'Un-Do', "Statusbar Un-Do")
secondm.Append(sm2)
self.Bind(wx.EVT_MENU, self.OnsMenu2, id=sm2.GetId())
menubar.Append(firstm,"File")
menubar.Append(secondm,"Edit")
self.SetMenuBar(menubar)
t = wx.StaticText(panel,-1,"Hello i'm a test", pos=(10,20))
def OnMenu1(self, event):
print("Menu item 1",event.GetId())
def OnMenu2(self, event):
print("Menu item 2",event.GetId())
def OnMenu3(self, event):
print("Menu item 3 Quit",event.GetId())
self.Destroy()
def OnsMenu1(self, event):
print("2nd Menu item 1",event.GetId())
def OnsMenu2(self, event):
print("2nd Menu item 2",event.GetId())
if __name__=='__main__':
app=wx.App()
frame=Test(None)
frame.Show()
app.MainLoop()
Спасибо! Я действительно ценю твою помощь!!