2010-04-01 27 views
10

Như được tham chiếu trong số previous question, tôi đang cố gắng tạo một chút gì đó giống như thuật sĩ trong chức năng. Tôi đã giải quyết trên một khung hình duy nhất với một sizer thêm vào nó. Tôi xây dựng các bảng cho mỗi màn hình mà tôi muốn người dùng nhìn thấy, thêm chúng vào sizer của khung, sau đó chuyển đổi giữa các bảng bằng cách .Hide() ing một bảng, sau đó gọi một tùy chỉnh .ShowYourself() trên bảng điều khiển tiếp theo. Rõ ràng, tôi muốn các nút vẫn ở trong cùng một vị trí khi người dùng tiến hành thông qua quy trình.Tại sao .Hide() ing và .Show() ing Panels trong Kết quả wxPython trong Sizer Thay đổi Bố cục?

Tôi đã liên kết với nhau hai bảng trong một vòng lặp vô hạn bằng các nút "Quay lại" và "Tiếp theo" để bạn có thể xem những gì đang diễn ra. Bảng điều khiển đầu tiên trông tuyệt vời; Mã số của tom10 hoạt động ở cấp độ đó, vì nó tránh được nỗ lực ban đầu, vượt trội của tôi với các đường viền bay theo mọi hướng. Và sau đó bảng điều khiển thứ hai dường như đã giảm xuống mức tối thiểu. Khi chúng ta quay trở lại bảng đầu tiên, sự co rút cũng đã xảy ra ở đây. Tại sao nó trông ổn trên bảng điều khiển đầu tiên, nhưng không phải sau khi tôi trở lại đó? Tại sao gọi .Fit() là cần thiết nếu tôi không muốn một màu xám 10 pixel x 10 pixel? Và nếu nó là cần thiết, tại sao .Fit() cho kết quả không phù hợp?

Vòng lặp vô hạn này dường như mô tả trải nghiệm của tôi với điều này: Tôi sửa bố cục trên bảng điều khiển, chỉ để thấy việc chuyển đổi làm hỏng bố cục cho các bảng khác. Tôi khắc phục sự cố đó, bằng cách sử dụng sizer_h.Add(self.panel1, 0) thay vì sizer_h.Add(self.panel1, 1, wx.EXPAND) và giờ bố cục của tôi lại bị tắt.

Cho đến nay, "giải pháp" của tôi là thêm mastersizer.SetMinSize((475, 592)) vào sizer chính của mỗi bảng (đã nhận xét trong mã bên dưới). Đây là một giải pháp cruddy bởi vì 1) Tôi đã phải tìm những con số mà làm việc bằng thử và sai (-5 pixel cho chiều rộng, -28 điểm ảnh cho chiều cao). 2) Tôi không hiểu tại sao vấn đề cơ bản vẫn xảy ra.

Giải pháp chính xác, không xấu? Thay vì thêm tất cả các bảng vào sizer của khung cùng một lúc, nên bảng chuyển đổi có liên quan đến .Detach() ing bảng điều khiển đó từ bộ sizer của khung và sau đó .Add() nhập bảng tiếp theo vào bộ sizer của khung không? Có một phương pháp .JustMakeThisFillThePanel() ẩn một nơi nào đó tôi đã bị mất trong cả hai wxWidgets và các tài liệu wxPython trực tuyến?

Tôi rõ ràng thiếu một thứ gì đó trong kiểu bố cục tinh thần của mình. Mã tối giản được dán bên dưới.

enter image description here

import wx 
import sys 


class My_App(wx.App): 

    def OnInit(self): 
     self.frame = My_Frame(None) 
     self.frame.Show() 
     self.SetTopWindow(self.frame) 
     return True 

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


class My_Frame(wx.Frame): 

    def __init__(self, image, parent=None,id=-1, title='Generic Title', pos=wx.DefaultPosition, style=wx.CAPTION | wx.STAY_ON_TOP):  

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

     sizer_h = wx.BoxSizer(wx.HORIZONTAL) 

     self.panel0 = User_Interaction0(self)  
     sizer_h.Add(self.panel0, 1, wx.EXPAND) 

     self.panel1 = User_Interaction1(self)  
     sizer_h.Add(self.panel1, 1, wx.EXPAND) 

     self.SetSizer(sizer_h) 

     self.panel0.ShowYourself() 

    def ShutDown(self): 
     self.Destroy() 


class User_Interaction0(wx.Panel): 

    def __init__(self, parent, id=-1): 

     wx.Panel.__init__(self, parent, id) 

     # master sizer for the whole panel 
     mastersizer = wx.BoxSizer(wx.VERTICAL) 
     #mastersizer.SetMinSize((475, 592)) 
     mastersizer.AddSpacer(15) 


     # build the top row 
     txtHeader = wx.StaticText(self, -1, 'Welcome to This Boring\nProgram', (0, 0)) 
     font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.BOLD) 
     txtHeader.SetFont(font) 
     txtOutOf = wx.StaticText(self, -1, '1 out of 7', (0, 0))     
     rowtopsizer = wx.BoxSizer(wx.HORIZONTAL) 
     rowtopsizer.Add(txtHeader, 3, wx.ALIGN_LEFT) 
     rowtopsizer.Add((0,0), 1) 
     rowtopsizer.Add(txtOutOf, 0, wx.ALIGN_RIGHT) 
     mastersizer.Add(rowtopsizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


     # build the middle row 
     text = 'PANEL 0\n\n' 
     text = text + 'This could be a giant blob of explanatory text.\n' 

     txtBasic = wx.StaticText(self, -1, text) 
     font = wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL) 
     txtBasic.SetFont(font) 
     mastersizer.Add(txtBasic, 1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


     # build the bottom row 
     btnBack = wx.Button(self, -1, 'Back') 
     self.Bind(wx.EVT_BUTTON, self.OnBack, id=btnBack.GetId()) 
     btnNext = wx.Button(self, -1, 'Next') 
     self.Bind(wx.EVT_BUTTON, self.OnNext, id=btnNext.GetId()) 
     btnCancelExit = wx.Button(self, -1, 'Cancel and Exit') 
     self.Bind(wx.EVT_BUTTON, self.OnCancelAndExit, id=btnCancelExit.GetId()) 
     rowbottomsizer = wx.BoxSizer(wx.HORIZONTAL) 
     rowbottomsizer.Add(btnBack, 0, wx.ALIGN_LEFT) 
     rowbottomsizer.AddSpacer(5) 
     rowbottomsizer.Add(btnNext, 0) 
     rowbottomsizer.AddSpacer(5) 
     rowbottomsizer.AddStretchSpacer(1) 
     rowbottomsizer.Add(btnCancelExit, 0, wx.ALIGN_RIGHT) 
     mastersizer.Add(rowbottomsizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 

     # finish master sizer 
     mastersizer.AddSpacer(15) 
     self.SetSizer(mastersizer) 

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


    def ShowYourself(self): 
     self.Raise() 
     self.SetPosition((0,0)) 
     self.Fit() 
     self.Show() 


    def OnBack(self, event): 
     self.Hide() 
     self.GetParent().panel1.ShowYourself() 

    def OnNext(self, event): 
     self.Hide() 
     self.GetParent().panel1.ShowYourself() 

    def OnCancelAndExit(self, event): 
     self.GetParent().ShutDown() 


class User_Interaction1(wx.Panel): 

    def __init__(self, parent, id=-1): 

     wx.Panel.__init__(self, parent, id) 

     # master sizer for the whole panel 
     mastersizer = wx.BoxSizer(wx.VERTICAL) 
     #mastersizer.SetMinSize((475, 592)) 
     mastersizer.AddSpacer(15) 


     # build the top row 
     txtHeader = wx.StaticText(self, -1, 'Read about This Boring\nProgram', (0, 0)) 
     font = wx.Font(16, wx.DEFAULT, wx.NORMAL, wx.BOLD) 
     txtHeader.SetFont(font) 
     txtOutOf = wx.StaticText(self, -1, '2 out of 7', (0, 0))     
     rowtopsizer = wx.BoxSizer(wx.HORIZONTAL) 
     rowtopsizer.Add(txtHeader, 3, wx.ALIGN_LEFT) 
     rowtopsizer.Add((0,0), 1) 
     rowtopsizer.Add(txtOutOf, 0, wx.ALIGN_RIGHT) 
     mastersizer.Add(rowtopsizer, 0, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


     # build the middle row 
     text = 'PANEL 1\n\n' 
     text = text + 'This could be a giant blob of boring text.\n' 

     txtBasic = wx.StaticText(self, -1, text) 
     font = wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL) 
     txtBasic.SetFont(font) 
     mastersizer.Add(txtBasic, 1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 


     # build the bottom row 
     btnBack = wx.Button(self, -1, 'Back') 
     self.Bind(wx.EVT_BUTTON, self.OnBack, id=btnBack.GetId()) 
     btnNext = wx.Button(self, -1, 'Next') 
     self.Bind(wx.EVT_BUTTON, self.OnNext, id=btnNext.GetId()) 
     btnCancelExit = wx.Button(self, -1, 'Cancel and Exit') 
     self.Bind(wx.EVT_BUTTON, self.OnCancelAndExit, id=btnCancelExit.GetId()) 
     rowbottomsizer = wx.BoxSizer(wx.HORIZONTAL) 
     rowbottomsizer.Add(btnBack, 0, wx.ALIGN_LEFT) 
     rowbottomsizer.AddSpacer(5) 
     rowbottomsizer.Add(btnNext, 0) 
     rowbottomsizer.AddSpacer(5) 
     rowbottomsizer.AddStretchSpacer(1) 
     rowbottomsizer.Add(btnCancelExit, 0, wx.ALIGN_RIGHT) 
     mastersizer.Add(rowbottomsizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=15) 

     # finish master sizer 
     mastersizer.AddSpacer(15) 
     self.SetSizer(mastersizer) 

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


    def ShowYourself(self): 
     self.Raise() 
     self.SetPosition((0,0)) 
     self.Fit() 
     self.Show() 


    def OnBack(self, event): 
     self.Hide() 
     self.GetParent().panel0.ShowYourself() 

    def OnNext(self, event): 
     self.Hide() 
     self.GetParent().panel0.ShowYourself() 

    def OnCancelAndExit(self, event): 
     self.GetParent().ShutDown() 


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


if __name__ == '__main__': 
    main() 
+0

Tôi sẽ xem xét vấn đề này. –

+0

nó hoạt động tốt trên GTK –

+0

Tôi tự hỏi nếu có một số khác biệt về chức năng giữa GTK và Windows 7 (nền tảng mục tiêu của tôi) mà không được hạch toán vào phiên bản hiện tại của wxPython cho Windows. Đó là tiện dụng để biết, Steven. Nó có nghĩa là có lẽ cách tôi nghĩ về điều này không hoàn toàn tắt. – MetaHyperBolic

Trả lời

16

Tôi nghĩ rằng tôi figured it out. Thay vì các cuộc gọi đến và ShowHide phương pháp của tấm, bạn cần phải gọi ShowHide phương pháp của sizer root:

self.Show() 

trở thành

self.GetParent().GetSizer().Show(self) 

... và vân vân.

Ngoài ra, sau mỗi cuộc gọi, bạn cần

self.GetParent().GetSizer().Layout() 
+0

Tôi đã làm điều đó. Tôi đã di chuyển câu lệnh self.SetSizer (sizer_h) trong lớp My_Frame trước khi các bảng được tạo ra, hoặc self.GetParent(). GetSizer() trả về None. Sau đó, nó chắc chắn tìm thấy sizer. Nhưng, self.GetParent(). GetSizer(). Hiển thị (self) trả về "False" trên cuộc gọi đầu tiên và tôi thấy cả hai tấm được ghép lại với nhau trên khung. Khi tôi bắt đầu nhấp vào nút Quay lại và Tiếp theo, chúng tôi sẽ quay trở lại hành vi tương tự như kéo kích thước bảng điều khiển xuống một cái gì đó nhỏ hơn nhiều so với khung hình. Tại thời điểm đó, self.GetParent(). GetSizer() Hiển thị (self) đang trả về True trong phương thức ShowYourself. – MetaHyperBolic

+0

Ah, và tôi đã tinh chỉnh chương trình của mình khi bạn thêm Bố cục! Về để cho rằng một shot. – MetaHyperBolic

+0

Đã hoạt động! Điều đó chỉ được gọi ở cuối hàm ShowYourself(). Vì vậy, vấn đề khái niệm của tôi là tôi đã bỏ qua hệ thống phân cấp của sizers, và giải pháp của bạn là chúng cũng phải được gọi. Bạn có một danh sách mong muốn Amazon, nơi tôi có thể mua cho bạn một cuốn sách? Nghiêm túc, vấn đề đặc biệt này khiến tôi khá thất vọng. – MetaHyperBolic

2

Yeah, tôi biết điều này đã được trả lời, nhưng ở đây bạn đi anyway:

Bạn chỉ nên phải gọi Bố cục() trên bảng điều khiển của cha mẹ, vì vậy một cái gì đó như self.GetParent(). Layout() nên làm các trick.Xem bài viết này: http://www.blog.pythonlibrary.org/2010/06/16/wxpython-how-to-switch-between-panels/

Nếu bạn muốn các nút để luôn hiển thị, tạo ra hai tấm trong một sizer dọc. Một trên đầu trang sẽ hiển thị các bảng của bạn và một ở phía dưới sẽ hiển thị các nút. Sau đó sử dụng PubSub hoặc một cái gì đó để giao tiếp giữa chúng.

Các vấn đề liên quan