#python-3.x #wxpython #wxgrid
Вопрос:
У меня есть фрейм, содержащий сетку, строки которой заполнены данными из моего api, поэтому пользователь редактирует данные из сетки, и я хочу, чтобы они были сохранены, когда пользователь закроет, нажмите X, чтобы закрыть фрейм, поэтому я делаю это
title = "Datos"
def __init__(self,title,parent=None):
wx.Frame.__init__(self, parent=parent, title=title)
user=self.get_ser()
self.Show()
panel=wx.Panel(self, -1)
myGrid = gridlib.Grid(panel)
user_data = json.loads(self.decrypt(self.get_data(user)))
print(user_data)
myGrid.CreateGrid(len(user_data), 3)
myGrid.SetColLabelValue(0, "WEB")
myGrid.SetColLabelValue(1, "USERNAME")
myGrid.SetColLabelValue(2, "PASSWORD")
for i in range(0,len(user_data)):
myGrid.SetCellValue(i, 0, user_data[i]["web"])
myGrid.SetCellValue(i, 1, user_data[i]["username"])
myGrid.SetCellValue(i, 2, user_data[i]["password"])
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(myGrid, 1, wx.EXPAND)
panel.SetSizer(sizer)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
self.Bind(wx.EVT_CLOSE, self.OnClose(myGrid,user_data))
def OnClose(self, myGrid,user_data):
dlg = wx.MessageDialog(self,
"Do you really want to close this application?",
"Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
result = dlg.ShowModal()
dlg.Destroy()
if result == wx.ID_OK:
self.savedata(myGrid,user_data)
self.Destroy()
def savedata(self, myGrid,user_data):
for i in range(0,(len(user_data))):
print(myGrid.GetCellValue(i,0) " " myGrid.GetCellValue(i,1) " " myGrid.GetCellValue(i,2))
моя проблема в том, что при открытии кадра появляется всплывающее диалоговое окно, и я передаю myGrid, чтобы он мог читать содержимое каждой строки, когда пользователь закрывает кадр, чтобы я мог сохранить данные, в настоящее время я печатаю данные на консоли, чтобы проверить их
теперь мой вопрос в том, как я могу сохранить данные, когда пользователь нажимает X, я имею в виду, что я знаю, как сохранить данные, но я хочу, чтобы они были, когда пользователь закрывает кадр. Другой вопрос, как я могу расширить сетку при открытии кадра? когда он открыт, я должен изменить размер рамки, чтобы сетка расширилась
Ответ №1:
- У вас есть ошибка
self.Show
в начале вашего кода. EVENT_CLOSE
Отправляетevent
, поэтому вы не можете просто добавить что-то в параметры вызываемой подпрограммы (без использованияlambda
)- Если вы создаете
myGrid
член экземпляра класса , т. е. объявляете егоself.myGrid
, он доступен для запроса и изменения. Объявив его какmyGrid
простоlocal
переменную.
Если мы объединим это вместе с издевательской и измененной версией вашего кода, мы получим следующее:
import wx
import wx.grid as gridlib
class MainFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title)
#user=self.get_ser()
panel=wx.Panel(self, -1)
self.myGrid = gridlib.Grid(panel)
#user_data = json.loads(self.decrypt(self.get_data(user)))
user_data = [["web1","user1","password1"],["web1","user2","password2"],["web3","user3","password3"]]
print(user_data)
self.myGrid.CreateGrid(len(user_data), 3)
self.myGrid.SetColLabelValue(0, "WEB")
self.myGrid.SetColLabelValue(1, "USERNAME")
self.myGrid.SetColLabelValue(2, "PASSWORD")
for i in range(0,len(user_data)):
self.myGrid.SetCellValue(i, 0, user_data[i][0])
self.myGrid.SetCellValue(i, 1, user_data[i][1])
self.myGrid.SetCellValue(i, 2, user_data[i][2])
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.myGrid, 1, wx.EXPAND)
panel.SetSizer(sizer)
self.Bind(wx.EVT_CLOSE, self.OnClose)
self.SetBackgroundColour(wx.Colour(100,100,100))
self.Centre()
self.Show()
def OnClose(self, event):
dlg = wx.MessageDialog(self,
"Do you really want to close this application?",
"Confirm Exit", wx.OK|wx.CANCEL|wx.ICON_QUESTION)
result = dlg.ShowModal()
dlg.Destroy()
if result == wx.ID_OK:
self.savedata()
self.Destroy()
def savedata(self):
gr = self.myGrid.GetNumberRows()
for i in range(0,(gr)):
print(self.myGrid.GetCellValue(i,0) " " self.myGrid.GetCellValue(i,1) " " self.myGrid.GetCellValue(i,2))
app = wx.App()
MainFrame(None, "Data")
app.MainLoop()
Как вы можете видеть OnClose
, принимает событие, суть здесь в том, что в данном случае вы знаете, откуда исходит событие и что это Близкое событие.
Подпрограмме savedata, также в этом случае, не нужно знать, что сохранять, есть только myGrid. Тем не менее, мы могли бы отправить event object
, если бы были какие-либо сомнения, или вызвать разные процедуры сохранения для разных объектов.
Нас не интересует оригинал userdata
, переданный в сетку, так как он почти наверняка изменился, поэтому мы запрашиваем сетку, чтобы узнать, сколько строк нужно проверить.
Наконец, мы можем получить доступ к данным в таблице и сохранить их или, в данном случае, распечатать.
N. B. Возможно, вы захотите рассмотреть вариант, при котором вы откажетесь от редактирования и выйдете. В нынешнем виде это сохранение, иначе вы обречены редактировать данные навсегда.
Результат экономии:
web1 user1 password1
Stackoverflow.com Rodrigo xXx
web3 user3 password3
Комментарии:
1. оооо, я делал это плохим способом, исправил это с вашей помощью, большое вам спасибо!