【问题标题】:Python - help on custom wx.Python (pyDev) classPython - 自定义 wx.Python (pyDev) 类的帮助
【发布时间】:2010-06-08 01:38:37
【问题描述】:

我在这个程序上遇到了死胡同。我正在尝试构建一个类,让我在使用时控制按钮的 BIP。到目前为止,这就是我所拥有的(见下文。)它一直在运行这个奇怪的错误TypeError: 'module' object is not callable - 我来自 C++ 和 C#(出于某种原因,#include... 容易得多),不知道这意味着什么,谷歌没有帮助,所以...我知道我需要一些真正的语法方面的帮助 - 任何事情都会有帮助。我知道这里有 很多 问题,非常感谢您的帮助!

注意:找到的基本代码 here 用于创建此“自定义按钮类”的骨架

自定义按钮

import wx
from wxPython.wx import *

class Custom_Button(wx.PyControl):

                                    # The BMP's
# AM I DOING THIS RIGHT? - I am trying to get empty 'global' 
# variables within the class
    Mouse_over_bmp = None #wxEmptyBitmap(1,1,1)   # When the mouse is over
    Norm_bmp = None #wxEmptyBitmap(1,1,1)         # The normal BMP
    Push_bmp = None #wxEmptyBitmap(1,1,1)         # The down BMP

    Pos_bmp = wx.Point(0,0)         # The posisition of the button

    def __init__(self, parent, NORM_BMP, PUSH_BMP, MOUSE_OVER_BMP,
                 pos, size, text="", id=-1, **kwargs):
        wx.PyControl.__init__(self,parent, id, **kwargs)

# The conversions, hereafter, were to solve another but. I don't know if it is 
# necessary to do this since the source being given to the class (in this case)
# is a BMP - is there a better way to prevent an error that i have not
# stumbled accost? 

        # Set the BMP's to the ones given in the constructor
        self.Mouse_over_bmp = wx.Bitmap(wx.Image(MOUSE_OVER_BMP, wx.BITMAP_TYPE_ANY).ConvertToBitmap())
        self.Norm_bmp = wx.Bitmap(wx.Image(NORM_BMP, wx.BITMAP_TYPE_ANY).ConvertToBitmap())
        self.Push_bmp = wx.Bitmap(wx.Image(PUSH_BMP, wx.BITMAP_TYPE_ANY).ConvertToBitmap())
        self.Pos_bmp = self.pos

        self.Bind(wx.EVT_LEFT_DOWN, self._onMouseDown)
        self.Bind(wx.EVT_LEFT_UP, self._onMouseUp)
        self.Bind(wx.EVT_LEAVE_WINDOW, self._onMouseLeave)
        self.Bind(wx.EVT_ENTER_WINDOW, self._onMouseEnter)
        self.Bind(wx.EVT_ERASE_BACKGROUND,self._onEraseBackground)
        self.Bind(wx.EVT_PAINT,self._onPaint)

        self._mouseIn = self._mouseDown = False

    def _onMouseEnter(self, event):
        self._mouseIn = True

    def _onMouseLeave(self, event):
        self._mouseIn = False

    def _onMouseDown(self, event):
        self._mouseDown = True

    def _onMouseUp(self, event):
        self._mouseDown = False
        self.sendButtonEvent()

    def sendButtonEvent(self):
        event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
        event.SetInt(0)
        event.SetEventObject(self)
        self.GetEventHandler().ProcessEvent(event)

    def _onEraseBackground(self,event):
        # reduce flicker
        pass

    def _onPaint(self, event):
        dc = wx.BufferedPaintDC(self)
        dc.SetFont(self.GetFont())
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        dc.DrawBitmap(self.Norm_bmp)

        # draw whatever you want to draw
        # draw glossy bitmaps e.g. dc.DrawBitmap
        if self._mouseIn:   # If the Mouse is over the button
            dc.DrawBitmap(self, self.Mouse_over_bmp, self.Pos_bmp, useMask=False)
        if self._mouseDown: # If the Mouse clicks the button
            dc.DrawBitmap(self, self.Push_bmp, self.Pos_bmp, useMask=False)

Main.py

​​>
import wx
import Custom_Button
from wxPython.wx import *

ID_ABOUT = 101
ID_EXIT  = 102

class MyFrame(wx.Frame):
    def __init__(self, parent, ID, title):
        wxFrame.__init__(self, parent, ID, title,
                         wxDefaultPosition, wxSize(400, 400))

        self.CreateStatusBar()
        self.SetStatusText("Program testing custom button overlays")
        menu = wxMenu()
        menu.Append(ID_ABOUT, "&About", "More information about this program")
        menu.AppendSeparator()
        menu.Append(ID_EXIT, "E&xit", "Terminate the program")
        menuBar = wxMenuBar()
        menuBar.Append(menu, "&File");
        self.SetMenuBar(menuBar)

        self.Button1 = Custom_Button(self, parent, -1, 
                                "D:/Documents/Python/Normal.bmp", 
                                "D:/Documents/Python/Clicked.bmp",
                                "D:/Documents/Python/Over.bmp",
                                wx.Point(200,200), wx.Size(300,100))

        EVT_MENU(self, ID_ABOUT, self.OnAbout)
        EVT_MENU(self, ID_EXIT,  self.TimeToQuit)

    def OnAbout(self, event):
        dlg = wxMessageDialog(self, "Testing the functions of custom "
                              "buttons using pyDev and wxPython",
                              "About", wxOK | wxICON_INFORMATION)
        dlg.ShowModal()
        dlg.Destroy()


    def TimeToQuit(self, event):
        self.Close(true)



class MyApp(wx.App):
    def OnInit(self):
        frame = MyFrame(NULL, -1, "wxPython | Buttons")
        frame.Show(true)
        self.SetTopWindow(frame)
        return true

app = MyApp(0)
app.MainLoop()

错误(和回溯)

/home/wallter/python/Custom Button overlay/src/Custom_Button.py:8: DeprecationWarning: The wxPython compatibility package is no longer automatically generated or actively maintained.  Please switch to the wx package as soon as possible.

无论何时使用 wxPython 任何帮助,我都无法解决这个问题?

  from wxPython.wx import *
Traceback (most recent call last):
  File "/home/wallter/python/Custom Button overlay/src/Main.py", line 57, in <module>
    app = MyApp(0)
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7978, in __init__
    self._BootstrapApp()
  File "/usr/lib/python2.6/dist-packages/wx-2.8-gtk2-unicode/wx/_core.py", line 7552, in _BootstrapApp
    return _core_.PyApp__BootstrapApp(*args, **kwargs)
  File "/home/wallter/python/Custom Button overlay/src/Main.py", line 52, in OnInit
    frame = MyFrame(NULL, -1, "wxPython | Buttons")
  File "/home/wallter/python/Custom Button overlay/src/Main.py", line 32, in __init__
    wx.Point(200,200), wx.Size(300,100))
TypeError: 'module' object is not callable

我尝试删除“wx.Point(200,200), wx.Size(300,100))”只是为了让错误向上移动到上面的行。我声明对了吗?帮忙?

使用此代码的先前问题:here

【问题讨论】:

    标签: python wxpython custom-controls class-design pydev


    【解决方案1】:

    注释掉这整件事,错误消失了,弹出了一个窗口:

     self.Button1 = Custom_Button(self, parent, -1, 
                                  "D:/Documents/Python/Normal.bmp", 
                                  "D:/Documents/Python/Clicked.bmp",
                                  "D:/Documents/Python/Over.bmp",
                                  wx.Point(200,200), wx.Size(300,100))
    

    所以到这里来……

    好的,找到问题了:

    这是导入自定义按钮。那只是导入模块。您想在该模块中使用具有相同名称的类:

    from Custom_Button import Custom_Button
    

    这个问题已经解决了。然后你可以继续下一个错误...

    对我来说,立即发现问题有点困难,因为您的编程风格与 Python 不同。与其他编程语言不同,Python 在文档中定义了特定的编程风格。这里和那里有一些细微的偏差,但总的来说,大多数优秀的 Python 开发人员都非常关注它,因为它很有意义并且有助于更容易地发现问题。

    Official Python Style Guide

    Google Version

    Google 版本增加了更多内容,甚至更加严格。

    所以在这种情况下,模块文件应该命名为 custom_button.py 和 main.py。该类应命名为 CustomButton。

    【讨论】:

    • 有什么替代方案?我还没有找到另一种导入 WX 库的方法。
    • 只需导入您将在程序中实际使用的模块,而不是所有内容。让事情更容易找到 - 以及这个函数的来源等等。
    【解决方案2】:

    当您在 Python 中导入模块时,将其视为在 C# 中导入上一级命名空间

    例如在C#中,当你说
    import System.IO;你可以指定
    var file = new File("a.txt");
    但是如果你只说import System;你必须说
    var file = new IO.File("a.txt");

    在 Python 中,如果你做了等效的 import System.IO,你仍然需要说
    file = IO.File("a.txt")

    为了不需要在 Python 中添加前缀,您需要说
    from System.IO import Filefrom System.IO import *,这更像是 C# 版本。

    能够指定特定类的好处是当您拥有包含大量类的命名空间时,或者您要导入的 2 个模块中的类名可能有冲突。在 C# 中,您需要为命名空间命名或指定全名,而您可以在 Python 中导入所需的特定名称。

    【讨论】:

      猜你喜欢
      • 2018-04-17
      • 2014-12-02
      • 2011-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      相关资源
      最近更新 更多