質問

I have a wxApplication with several wxTextCtrl, for example:

self.tc1 = wx.TextCtrl(self.panel,-1,pos=(100,150),size=(60,20))
self.tc2 = wx.TextCtrl(self.panel,-1,pos=(100,170),size=(60,20))
self.tc3 = wx.TextCtrl(self.panel,-1,pos=(100,190),size=(60,20))
self.tc_all = [self.tc1, self.tc2, self.tc3]

After the User entered different values and clicked on a button, I want to sort the entered values, for example the user entered this:

>>> values = [self.tc1.GetValue(), self.tc2.GetValue(), self.tc3.GetValue()]
>>> print values
[2,1,3]

I want to sort these values and change it inside the TextCtrls, so I do:

values.sort()
for i in range(len(values)):
    self.tc_all[i].SetValue(values[i])

First the values change correctly, but when I hover with the mouse on each TextCtrl, then they change back into the old value. I tried to add a self.panel.Layout(), but the problem still occurs.

Edit: I changed my sizer setup, now my values not even change - but I don't know what's wrong:

self.inputsizer = wx.BoxSizer(wx.VERTICAL)
for i in range(self.ticks):
    self.inputsizer.Add(self.tc_all[i], 0, wx.ALL|wx.EXPAND, 2)
self.inputpanel.SetSizer(self.inputsizer)

and on my event (when inputs shall be sorted):

self.inputsizer.Layout()

Edit2: It's getting far from original question, don't know if I should have started a new question?! Explanation: Somewhere in class interpolation I save an image ('tmp.png') which I want to display on Panel pageThree. When I don't draw any image, everything works fine. But drawing an image is important part of my program, so here two problems occur: 1) My values inside the TextCtrls "hide": Just after mousehover they appear as expected (sorted). 2) The wrong image is drawn: I get a screenshot of my panel as image at the first click on my button; when I press the button twice, the correct image is drawn.

import wx

class MainFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          "Pyramid App",size=(800,600),pos=((wx.DisplaySize()[0]-800)/2,(wx.DisplaySize()[1]-600)/2),style= wx.SYSTEM_MENU | wx.CAPTION | wx.MINIMIZE_BOX | wx.CLOSE_BOX)

        self.p = wx.Panel(self,size=(800,600),pos=(0,0))
        self.p.Hide()
        self.PageThree = pageThree(self)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.PageThree, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.Layout()

class pageThree(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent=parent,size=(800,525))
        self.myparent=parent
        self.pageThree=wx.Panel(self,size=(800,525))
        self.widgets()

    def widgets(self):
        self.ticks = 10
        self.tc_all = [None for i in range(self.ticks)]
        self.inputsizer = wx.BoxSizer(wx.VERTICAL)
        for i in range(self.ticks):
            self.tc_all[i] = wx.TextCtrl(self.pageThree, pos=(20+10+160*(i/10),265+10+25*(i%10)),size=(80,20))
            self.inputsizer.Add(self.tc_all[i], 0, wx.ALL|wx.EXPAND, 2)
        self.pageThree.SetSizer(self.inputsizer)

        self.startBtn = wx.Button(self.pageThree,label="button",pos=(350,102),size=(100,30))
        self.Bind(wx.EVT_BUTTON, self.start, self.startBtn)

    def start(self, event):
        h = []
        for i in range(self.ticks):
            val = self.tc_all[i].GetValue()
            if not (val==''):
                h.append(float(val))
        h.sort()
        h.reverse()
        hh = h + ['']*(self.ticks-len(h))
        for i in range(self.ticks):
            self.tc_all[i].SetValue(str(hh[i]))

        self.interp = interpolation(self.myparent)
        self.interp.run(h)

    def UpdatePicture(self):
        bitmap = wx.Bitmap('tmp.png', type=wx.BITMAP_TYPE_PNG)
        bitmap = self.scale_bitmap(bitmap, 400, 390)
        control = wx.StaticBitmap(self.pageThree, -1, bitmap)
        control.SetPosition((350,135))

    def scale_bitmap(self, bitmap, width, height):
        image = wx.ImageFromBitmap(bitmap)
        image = image.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
        result = wx.BitmapFromImage(image)
        return result

class interpolation():
    def __init__(self, parent):
        self.myparent=parent
        self.page3 = pageThree(self.myparent)

    def run(self, h):
        self.page3.UpdatePicture()

if __name__ == "__main__":
    app = wx.App()
    MainFrame().Show()
    app.MainLoop()
役に立ちましたか?

解決

Ok, the issue is with how your accessing the information, try getting at it through the sizer:

self.tc_all = []
for child in self.inputsizer.GetChildren():
    self.tc_all.append(child.GetWindow().GetValue())

self.tc_all = sorted(self.tc_all)

for child,item in zip(self.inputsizer.GetChildren(),self.tc_all):
    child.GetWindow().SetValue(item)

self.inputsizer.Layout()  

So here's whats going on here. Every sizer has children called "sizer items" (documentation here) which are representations of your items on the GUI. Calling GetChildren() on any sizer will return a list of all of that sizer's sizer items. Note that these are note the items themselves, so you need to take one more step, and that is the GetWindow() function. The result of GetWindow() on a sizer item is to return the actual item (or widget) that the sizer item represents, in the case a TextCtrl item. Once you have that, you can treat is as you normally would.

BE CAREFUL when using the GetChildren() function on a sizer that contains multiple items, as it returns all the children. So your code will break if you try to call SetValue() on something which does not support that method, such at StaticText

Hope this helps

EDIT: The actual answer was an issue with sizers resulting from nesting panels. Editing the sizers in the nested panel caused the strange behavior noted in the question.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top