4

プログラムの現在の設定を保存して、特に指定しない限り、プログラムの再起動またはコンピューターの再起動時に同じままにする方法を知りたいです。たとえば、Windows の既定のプログラムである付箋には、テキストが保存されるため、コンピューターをシャットダウンした後でも使用できます。

インポートできるモジュールはありますか? 私のプログラムは基本的にタスク リスト プログラムであり、リストに項目を追加し、wxPython チェック ボックスを使用してそれをチェックします。プログラムの終了後も状態を維持する方法はありますか?

誰かが私のコードの例を見せてくれれば幸いです。心配しないでください。単純にコピーするだけでは終わりません。それは私にとって学習経験とみなされるので、将来それを使用することができます. ありがとう。

これが私のプログラムです:

import wx, sys,os

mylist = []

class test(wx.Frame):

def __init__(self, parent, id):


    self.count = 1
    #Frame
    wx.Frame.__init__(self,parent,id,'List',size = (200,500))
    #Panel
    self.panel = wx.Panel(self)
    item = wx.TextEntryDialog(None, "List Title")
    if item.ShowModal() == wx.ID_OK:
        print 'here'
        answer = item.GetValue()
        mylist.append(answer)
        print mylist
        windtitle = wx.StaticText(self.panel, -1, answer, (10,10))
        windtitle.SetForegroundColour("blue")


    addButton = wx.Button(self.panel, label = "+ Add", pos=(40,450), size = (60,-1))
    finishButton = wx.Button(self.panel, label = "Finish", pos=(110,450), size = (60,-1))

    self.Bind(wx.EVT_BUTTON, self.addtomenu, addButton)
    self.Bind(wx.EVT_BUTTON, self.finish, finishButton)

def finish(self, event):
    self.Destroy()
    sys.exit()

def addtomenu(self,event):

    newitem = wx.TextEntryDialog(None, "New Item")
    if newitem.ShowModal() == wx.ID_OK:
        count = len(mylist)+1
        print count
        yaxis = 20*count
        if count == 21:
            wx.StaticText(self.panel, -1, "List To Full", (10, yaxis))
        else:
            answer = newitem.GetValue()
            mylist.append(answer)
            print mylist
            self.Bind(wx.EVT_CLOSE, self.closewindow)
            wx.CheckBox(self.panel, -1, answer, (10,yaxis), size = (200,-1)) 



def closewindow(self, event):
    self.Destroy()






if __name__ == "__main__":
    app=wx.PySimpleApp()  #Blood
    frame = test(parent=None, id = -1)  #Skin
    frame.Show()
    app.MainLoop()  #Heart
4

3 に答える 3

4

プログラムの状態をJSONファイルに保存する方法の例を次に示します。finishプログラムが終了したとき、または[完了]ボタンが閉じられたときに呼び出されるメソッドが既にあります。saveこれを使用して、状態をJSONファイルに保存するメソッドを呼び出すこともできます。

def finish(self, event):
    self.save()
    self.Destroy()
    sys.exit()

def save(self):
    windtitle = self.windtitle.GetLabelText()
    checkboxes = [{'checked': child.IsChecked(),
                   'label': child.GetLabel()}
                  for child in self.panel.GetChildren()
                  if isinstance(child, wx.CheckBox)]
    data = {
        'windtitle':windtitle,
        'checkboxes':checkboxes,
        }
    with open(CONFIGFILE, 'w') as f:
        json.dump(data, f)

そして、JSONデータを読み取ってGUIを再構成する方法は次のとおりです。

def load(self):
    if os.path.exists(CONFIGFILE):
        with open(CONFIGFILE, 'r') as f:
            data = json.load(f)
        title = data['windtitle']
        self.windtitle = wx.StaticText(self.panel, -1, title)
        self.vbox.Add(self.windtitle)
        for checkbox in data['checkboxes']:
            label = checkbox['label']
            cb = wx.CheckBox(
                self.panel, -1, checkbox['label'])
            self.vbox.Add(cb)                
            cb.SetValue(checkbox['checked'])
    else:
        self.create_windtitle()
    self.create_buttons()

例えば:

import wx, sys, os
import json

CONFIGFILE = os.path.expanduser('~/tasklist.json')
class test(wx.Frame):
    def __init__(self, parent, id):
        frame = wx.Frame.__init__(self, parent, id, 'List', size = (200,500))
        self.panel = wx.Panel(self)
        self.panelbox = wx.BoxSizer(wx.VERTICAL)                

        self.vbox = wx.BoxSizer(wx.VERTICAL)        
        self.load()

        self.panelbox.Add(self.vbox)        
        self.panelbox.Add(self.buttonbox)

        self.panel.SetSizer(self.panelbox)
        self.panelbox.Fit(self)

        self.Bind(wx.EVT_BUTTON, self.addtomenu, self.addButton)
        self.Bind(wx.EVT_BUTTON, self.finish, self.finishButton)
        self.Bind(wx.EVT_CLOSE, self.finish)

    def create_buttons(self):
        self.buttonbox = wx.BoxSizer(wx.VERTICAL)                
        self.addButton = wx.Button(
            self.panel, label = "+ Add")
        self.finishButton = wx.Button(
            self.panel, label = "Finish")
        self.buttonbox.Add(self.addButton)
        self.buttonbox.Add(self.finishButton)

    def create_windtitle(self):
        item = wx.TextEntryDialog(None, "List Title")
        if item.ShowModal() == wx.ID_OK:
            answer = item.GetValue()
            self.windtitle = wx.StaticText(self.panel, -1, answer)
            self.windtitle.SetForegroundColour("blue")

    def addtomenu(self, event):
        newitem = wx.TextEntryDialog(None, "New Item")
        if newitem.ShowModal() == wx.ID_OK:
            if len(self.mylist) > 5:
                wx.StaticText(self.panel, -1, "List To Full")
            else:
                answer = newitem.GetValue()
                cb = wx.CheckBox(self.panel, -1, answer)
                self.vbox.Add(cb)
        self.panelbox.Fit(self)

    def finish(self, event):
        self.save()
        self.Destroy()
        sys.exit()

    @property
    def mylist(self):
        return [ child.GetLabel()
                 for child in self.panel.GetChildren()
                 if isinstance(child, wx.CheckBox) ]

    def save(self):
        windtitle = self.windtitle.GetLabelText()
        checkboxes = [{'checked': child.IsChecked(),
                       'label': child.GetLabel()}
                      for child in self.panel.GetChildren()
                      if isinstance(child, wx.CheckBox)]
        data = {
            'windtitle':windtitle,
            'checkboxes':checkboxes,
            }
        with open(CONFIGFILE, 'w') as f:
            json.dump(data, f)

    def load(self):
        if os.path.exists(CONFIGFILE):
            with open(CONFIGFILE, 'r') as f:
                data = json.load(f)
            title = data['windtitle']
            self.windtitle = wx.StaticText(self.panel, -1, title)
            self.vbox.Add(self.windtitle)
            for checkbox in data['checkboxes']:
                label = checkbox['label']
                cb = wx.CheckBox(
                    self.panel, -1, checkbox['label'])
                self.vbox.Add(cb)                
                cb.SetValue(checkbox['checked'])
        else:
            self.create_windtitle()
        self.create_buttons()

if __name__ == "__main__":
    app = wx.PySimpleApp()  #Blood
    frame = test(parent = None, id = -1)  #Skin
    frame.Show()
    app.MainLoop()  #Heart

ちなみに、GUIにウィジェットを配置するために明示的な位置を使用しないでください。その道は狂気につながる。位置(例pos = (10,yaxis))を使用する場合、GUIが大きくなるにつれて、レイアウトの変更がますます困難になります。すべての要素の位置は他の要素の位置に依存するようになり、すぐに管理できなくなります。

すべてのGUIフレームワークは、見栄えの良いレイアウトを実現するための賢明な方法を提供します。なじみはありませんwxpythonが、使っているようBoxSizersです。上で使用したレイアウトは非常に基本的なものです。wxpythonのレイアウトデザインパターンを研究することで、はるかに優れたレイアウトを実現できると確信しています。


時々、ウィジェットのすべての属性とメソッドが何であるかを知る必要がありました。たとえば、パネルにどのチェックボックスが含まれているかをパネルに尋ねる方法がわかりませんでした。私はこの関数を使用してそれを見つけました:

def describe(obj):
    for key in dir(obj):
        try:
            val = getattr(obj, key)
        except AttributeError:
            continue
        if callable(val):
            help(val)
        else:
            print('{k} => {v}'.format(k = key, v = val))
        print('-'*80)

describe(self.panel)

これは私がutils_debugで持っていた関数です。

于 2013-01-06T15:02:17.530 に答える
1

ボタンの状態をリストや dict のようなデータ コレクションに保存したい場合は、データをマーシャリングまたはシリアル化できます。

例えば

my_button_states = {"button1":True}
import json
with open("states.json", 'w') as output:
    json.dump(my_button_states, output)

後でjsonをプログラムに再ロードし、dictをループしてボタンを設定します

例えば

with open("states.json") as fp:
    my_button_states = json.loads(fp)
# inside your frame or something.... idk where you put them.
for button, state in my_button_states.iteritems():
    setattr(self, button, state)

使用するjsonか、提案する人もいますpicklejson、これにはより良い選択かもしれません。

コードを使用して、おそらく次のようなことをしたいと思うでしょう

json.dump(mylist, output)

もちろん私の例では

于 2013-01-06T14:56:43.987 に答える