Подходит wx.Sizer (s) для работы? - PullRequest
0 голосов
/ 30 марта 2010

У меня есть пробел, в котором я хотел бы, чтобы определенные элементы (представленные здесь как A, B, D и G) находились в своем «углу» дизайна. Углы должны располагаться так, как если бы каждый из четырех элементов отталкивал другой; Прямоугольник. Это должно содержаться в неизменяемой панели. У меня будет несколько похожих панелей, и я хочу, чтобы расположение элементов было как можно более одинаковым. (Мне нужно что-то более сложное, чем wx.Wizard, но с той же общей идеей.)

AAAAAAAAAA      BB


CCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCC
CCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCC


DDD EEE FFF    GGG

A представляет текст крупным шрифтом.

B представляет собой числовой индикатор прогресса (например, «1 из 7») мелким шрифтом.

C представляет большой блок текста.

D, E, F и G - кнопки.

Кнопка G отделена от других для функциональности.

Я попытался вложить wx.BoxSizers (горизонтальные блоки внутри одного вертикального блока) без удачи. Моя первая проблема с wx.BoxSizer заключается в том, что .SetMinSize в моем последнем ряду не было выполнено. Вторая проблема заключается в том, что я понятия не имею, как заставить кнопку G «занимать место», не увеличивая ее размер, или как я могу зажать ее у правого и нижнего края.

Я пытался использовать wx.GridBagSizer, но столкнулся с совершенно другими проблемами.

После просмотра различных онлайн-уроков и wxPython в действии я немного разочарован. Соответствующие форумы видят активность раз в две недели. «Игра с этим» ни к чему не привела; Мне кажется, что я пытаюсь разгладить горб на плохо уложенном ковре.

Ответы [ 3 ]

3 голосов
/ 31 марта 2010

Используя BoxSizers и некоторые флаги, такие как wx.EXPAND и wx.ALIGN_RIGHT и т. Д., Вы можете получить то, что вы хотите. Вот пример

import wx
import string
AF = string.ascii_uppercase[:7]

class MyFrame(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, size=(300,300))

        a, b, c, d, e, f, g = [wx.Button(self, -1, 4*c) for c in AF]
        a.SetMaxSize((200,100))   # 'a' won't get bigger than 200 wide

        # build the top row (with sizers I usually work from inside to out)
        hs0 = wx.BoxSizer(wx.HORIZONTAL)
        hs0.Add(a, 1, wx.ALIGN_LEFT)  # 1 here means expand with weight 1
        hs0.Add((0,0), 1)  # also expand the spacing
        hs0.Add(b, 0, wx.ALIGN_RIGHT)  # 0 means don't expand this

        # build the bottom row
        hs1 = wx.BoxSizer(wx.HORIZONTAL)
        hs1.Add(d, 0, wx.ALIGN_LEFT)
        hs1.Add((10,10), 0)
        hs1.Add(e, 0)
        hs1.Add((10,10), 0)
        hs1.Add(f, 0)
        hs1.Add((10, 10), 1)
        hs1.Add(g, 0, wx.ALIGN_RIGHT)

        # stack the rows vertically
        vs = wx.BoxSizer(wx.VERTICAL)
        vs.Add(hs0, flag=wx.EXPAND)   # expand in the orthogonal direction to sizer (here horizontal)
        vs.Add(c, 1, flag=wx.EXPAND)  
        vs.Add(hs1, flag=wx.EXPAND)
        self.SetSizer(vs)

app = wx.PySimpleApp()
frame = MyFrame()
frame.Show(1)
app.MainLoop()

альтернативный текст http://i41.tinypic.com/14vl7jd.png

1 голос
/ 30 марта 2010

Прежде всего, вам нужен вертикальный классификатор, чтобы разделить окно на 3 строки: AB, C и DEFG:

frame_sizer = wx.BoxSizer(wx.VERTICAL)

Далее вам необходим горизонтальный размер первого ряда:

first_sizer = wx.BoxSizer(wx.HORIZONTAL)
# add the items A and B to first_sizer
# now we add first_sizer to frame_sizer
frame_sizer.Add(first_sizer)

Затем для второй строки мы просто добавляем элемент управления C в классификатор:

frame_sizer.Add(C)

... проверяя следующее:

  • Элемент управления создается с указанным размером (через его конструктор)
  • Элемент управления имеет минимальный размер (C.SetMinSize())

Теперь, для последней строки, вероятно, лучше всего использовать другой горизонтальный калибратор.

wx.BoxSizer(wx.HORIZONTAL)
# add DEF
# now add some space between them
wx.AddSizer(10)
# now add G

Надеюсь, это работает для вас. Если нет, то лучше всего использовать дизайнер GUI, такой как wxSmith, в Code :: Blocks (который разработан для C ++, но может быть использован, по крайней мере, для того, чтобы понять, как все будет выглядеть - wxPython должен иметь 1-to -1 соответствие wxWidgets)

0 голосов
/ 31 марта 2010

У меня есть только один кадр. У меня есть несколько панелей, встроенных в раму. Все они скрыты, кроме одного. Кнопка «Далее» выполняет .Hide () на этой панели, а затем вызывает функцию с именем .ShowYourself. Я хотел что-то похожее на волшебника, которое вы можете увидеть в предыдущем вопросе

Я пытаюсь поставить на панель сортировщик. Как вы можете видеть из картинки http://tinypic.com/r/14nh651/5,, я не могу заставить сортировщик занять всю панель. Изображение не отображается при предварительном просмотре, поэтому здесь оно находится на http://tinypic.com/r/14nh651/5.

import wx
import sys

class MyApp(
    wx.App      # This makes a subclass of the wx.App class

):

def OnInit(self):
    # image = wx.Image('wxPython.jpg', wx.BITMAP_TYPE_JPEG)
    self.frame = MyFrame(None)
    self.frame.Show()
    self.SetTopWindow(self.frame)
    return True

def OnExit(self):
    print 'Dying ...'

####################################################################################################

class MyFrame(
    wx.Frame    # This makes a subclass of the wx.Frame class
    ):
    """Frame class that displays an image."""

    def __init__(self, 
        image, 
        parent=None,                # "None" as a parameter means this is a top-level window
        id=-1,                  # "-1" means automatically generate a new ID
        title='Generic Title',          # What words appear in the title bar?
        pos=wx.DefaultPosition,         # Where is the upper left-hand corner?
        style=wx.CAPTION | wx.STAY_ON_TOP   # Style with only a caption
        ):      

    """Create a wx.Frame instance and display image."""

    size = (500, 500)
    wx.Frame.__init__(self, parent, id, 'Program Title', pos, size, style)

    sizer_h = wx.BoxSizer(wx.HORIZONTAL)

    self.panelX = TestLayout3(self)     
    sizer_h.Add(self.panelX)

    self.SetSizer(sizer_h)

    self.panelX.ShowYourself()

def ShutDown(self):

        self.Destroy()

####################################################################################################

class TestLayout3(wx.Panel):

# 0 - Splash screen with "Next" and "Cancel and Exit" buttons

def __init__(self, parent, id=-1):
    size = (600, 600)
    wx.Panel.__init__(self, parent, id, size)

    a, b, c, d, e, f, g = [wx.Button(self, -1, 4*c) for c in 'ABCDEFG']
    a.SetMaxSize((200,100))   # 'a' won't get bigger than 200 wide

    # build the top row (with sizers I usually work from inside to out)
    hs0 = wx.BoxSizer(wx.HORIZONTAL)
    hs0.Add(a, 1, wx.ALIGN_LEFT)  # 1 here means expand with weight 1
    hs0.Add((0,0), 1)  # also expand the spacing
    hs0.Add(b, 0, wx.ALIGN_RIGHT)  # 0 means don't expand this

    # build the bottom row
    hs2 = wx.BoxSizer(wx.HORIZONTAL)
    hs2.Add(d, 0, wx.ALIGN_LEFT)
    hs2.Add((10,10), 0)
    hs2.Add(e, 0)
    hs2.Add((10,10), 0)
    hs2.Add(f, 0)
    hs2.Add((10, 10), 1)
    hs2.Add(g, 0, wx.ALIGN_RIGHT)

    # stack the rows vertically
    vs = wx.BoxSizer(wx.VERTICAL)
    vs.Add(hs0, flag=wx.EXPAND)   # expand in the orthogonal direction to sizer (here horizontal)
    vs.Add(c, 1, flag=wx.EXPAND)  
    vs.Add(hs2, flag=wx.EXPAND)
    self.SetSizer(vs)

    self.Raise()
    self.SetPosition((0,0))
    self.Fit()  
    self.Hide()


# reveal this panel
def ShowYourself(self):
    self.Raise()
    self.SetPosition((0,0))
    self.Fit()
    self.Show()


# what do we do when the "Back" button is clicked?
def OnBack(self, event):
    self.Hide()
    self.GetParent().panel1.ShowYourself()

# what do we do when the "Next" button is clicked?
def OnNext(self, event):
    self.Hide()
    self.GetParent().panel1.ShowYourself()

    ![# what do we do when the "Cancel and Exit" button is clicked?
    def OnCancelAndExit(self, event):
        self.GetParent().ShutDown()

####################################################################################################

def main():
    app = MyApp(redirect = False)
    app.MainLoop()

####################################################################################################

if __name__ == '__main__':
    main()][3]
...