微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 wxpython GUI 中开发类似组件的瓦片?

如何解决如何在 wxpython GUI 中开发类似组件的瓦片?

我一直在构建一个可以进行多次扫描的扫描仪。我想在类似于附加图像的网格或瓷砖中列出它们。我正在尝试的一种方法是为每个磁贴制作 Panel 类。但是由于有数千个扫描(图块),我担心程序的速度和效率。设计就是以此为动力的。

enter image description here

解决方法

首先,我创建了一个继承自 wx.Panel 的类,它将包含一个居中的图像、文本和按钮。在这个类中,我创建了每次初始化面板所需的方法:SetImage、SetText 和 SetButton。然后,从主框架类中,我初始化了几个 TilePanel 来显示它们。

最后,我为主类中的按钮设置了相同的事件处理程序。

在您提出的情况下,诀窍在于这 2 个 sizer:wx.BoxSizerwx.WrapSizer

看看这段代码(在这种情况下,我使用 wxWrapSizer 因为我希望面板在水平方向不适合时显示在彼此下方):

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import wx
from wx.lib.expando import ExpandoTextCtrl,EVT_ETC_LAYOUT_NEEDED


class MainFrame(wx.Frame):
    def __init__(self,*args,**kwds):
        # begin wxGlade: MainFrame.__init__
        kwds["style"] = kwds.get("style",0) | wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self,**kwds)
        self.SetSize((690,340))
        
        
        
        # Create 3 new panels:
        newPanel = TilePanel(self,wx.ID_ANY)
        newPanel.SetImage(wx.ArtProvider.GetBitmap(wx.ART_INFORMATION,wx.ART_MESSAGE_BOX,size=wx.Size(80,80)))
        newPanel.SetText("Lorem ipsum dolor sit amet,consectetur adipiscing elit. Vestibulum fringilla justo ut ante laoreet consectetur. Class aptent taciti sociosqu ad litora torquent per conubia nostra,per inceptos himenaeos.")            
        newPanel.SetButton("View More...",callback=self.OnMyCustomHandler)

        newPanel2 = TilePanel(self,wx.ID_ANY)
        newPanel2.SetImage(wx.ArtProvider.GetBitmap(wx.ART_WARNING,80)))
        newPanel2.SetText("Lorem ipsum dolor sit amet,per inceptos himenaeos.")            
        newPanel2.SetButton("View More...",callback=self.OnMyCustomHandler)

        newPanel3 = TilePanel(self,wx.ID_ANY)
        newPanel3.SetImage(wx.ArtProvider.GetBitmap(wx.ART_ERROR,80)))
        newPanel3.SetText("Lorem ipsum dolor sit amet,per inceptos himenaeos.")            
        newPanel3.SetButton("View More...",callback=self.OnMyCustomHandler)
        
        self._panels = []                         
        self._panels.append(newPanel)
        self._panels.append(newPanel2)
        self._panels.append(newPanel3)

        self.__set_properties()
        self.__do_layout()

    def __set_properties(self):
        self.SetTitle("frame")               
        self.SetBackgroundColour(wx.Colour(220,220,220))        

    def __do_layout(self):        
        # Create a wrap sizer:
        sizer_1 = wx.WrapSizer(wx.HORIZONTAL)

        # Add panels to the sizer:
        for panel in self._panels:
            sizer_1.Add(panel,wx.ALL,2)        

        self.SetSizer(sizer_1)
        self.Layout()
        
    def OnMyCustomHandler(self,event):
        print('{} has clicked'.format(event.GetEventObject().GetId()))        


# TilePanel Class
class TilePanel(wx.Panel):
    def __init__(self,**kwds):        
        kwds["style"] = kwds.get("style",0) | wx.TAB_TRAVERSAL
        wx.Panel.__init__(self,**kwds)
        self.text_ctrl_1 = ExpandoTextCtrl(self,wx.ID_ANY,"No text set",style=wx.BORDER_NONE | wx.TE_CENTRE | wx.TE_MULTILINE | wx.TE_NO_VSCROLL)
        self.button_1 = wx.Button(self,"No button text")
        self.stBmp = wx.StaticBitmap(self,wx.ID_ANY)
        self.sizer_flexi = wx.FlexGridSizer(3,1,0)
        self.__set_properties()
        self.__do_layout()        

    def __set_properties(self):        
        self.SetBackgroundColour(wx.Colour(255,255,255))
        self.text_ctrl_1.SetBackgroundColour(wx.Colour(255,255))
        self.text_ctrl_1.SetMinSize((200,-1))
        self.button_1.SetMinSize((100,40))
        self.button_1.SetBackgroundColour(wx.Colour(255,255))        

    def __do_layout(self):        
        self.SetSizer(self.sizer_flexi)
        self.sizer_flexi.Fit(self)
        self.sizer_flexi.AddGrowableRow(1)
        self.sizer_flexi.AddGrowableCol(0)
        self.Layout()
    
    def SetImage(self,bmp):
        self.stBmp.SetBitmap(bmp)
        self.sizer_flexi.Add(self.stBmp,wx.ALIGN_CENTER | wx.ALL,10)
        self.Layout()        
        
    def SetText(self,text):
        self.text_ctrl_1.SetValue(text)
        self.sizer_flexi.Add(self.text_ctrl_1,wx.EXPAND | wx.ALL,10)
        self.Layout()

    def SetButton(self,btnTitle,callback):
        self.button_1.SetLabel(btnTitle)
        self.button_1.Bind(wx.EVT_BUTTON,callback)
        self.sizer_flexi.Add(self.button_1,wx.ALIGN_CENTER | wx.BOTTOM,10)
        self.Layout()

# end of class TilePanel


# Main App:
class MyApp(wx.App):
    def OnInit(self):
        self.frame = MainFrame(None,"")
        self.SetTopWindow(self.frame)
        self.frame.Show()
        return True

# end of class MyApp

if __name__ == "__main__":
    app = MyApp(0)
    app.MainLoop()

结果如下: enter image description here

如果我改用 wx.BoxSizer,面板在不适合时会变窄。试试吧!

运行、更改和测试此代码,直到您理解它为止。

P.D.:我强烈建议您使用 wxGlade 在 wxPython 中设计接口。它将帮助您了解 sizer 如何比任何教程都更好地工作。

http://wxglade.sourceforge.net/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。