Python - справка по пользовательскому классу wx.Python (pyDev) - PullRequest
0 голосов
/ 08 июня 2010

Я зашел в тупик с этой программой.Я пытаюсь создать класс, который позволит мне контролировать BIP кнопки, когда она используется.до сих пор это то, что у меня есть (см. ниже.) Он продолжает запускать эту странную ошибку TypeError: 'module' object is not callable - я, исходя из C ++ и C # (по какой-то причине #include... намного проще), понятия не имею, что это значит,Google не помогает, так что ... Я знаю, что мне нужна некоторая реальная помощь с синтаксисом и тому подобное - все, что было бы полезно.Я знаю, что есть много вопросов в этом, я был бы очень признателен за помощь!

Примечание. Найденный базовый код здесь был использован для создания каркаса для этого «класса пользовательских кнопок»

Пользовательская кнопка

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))" только для того, чтобы ошибка поднялась до строки выше.Я объявил это правильно?help?

Предыдущие вопросы с этим кодом: здесь

Ответы [ 2 ]

2 голосов
/ 08 июня 2010

Закомментировал все это, и ошибка исчезла, и появилось окно:

 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))

Итак, куда-то сюда попасть ...

хорошо, нашел проблему:

Это импорт Custom_Button. Это просто импортирует модуль. Вместо этого вы хотите использовать класс с тем же именем в этом модуле, поэтому:

from Custom_Button import Custom_Button

И эта проблема исправлена. Затем вы можете перейти к следующей ошибке ...

Мне было немного трудно сразу увидеть проблему, потому что вы программируете в стиле, отличном от Python. В отличие от других языков программирования, в Python есть определенный стиль программирования, определенный в документе. Здесь и здесь есть небольшие отклонения, но в целом большинство хороших разработчиков Python довольно внимательно следят за этим, потому что это имеет смысл и облегчает обнаружение проблем.

Официальное руководство по стилю Python

Google Version

Версия Google добавляет больше и даже более ограничительна.

Так что в этом случае файлы модуля должны называться custom_button.py и main.py. Класс должен называться CustomButton.

1 голос
/ 08 июня 2010

Когда вы импортируете модуль в 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 File или from System.IO import *, что больше похоже на версию C #.

Преимущество возможности указывать определенные классы заключается в том, что у вас есть пространства имен с большим количеством классов или, возможно, существуют конфликтующие имена классов в 2 модулях, которые вы хотите импортировать. В C # вам нужно либо создать псевдоним пространства имен, либо указать полное имя, где вместо этого вы можете просто импортировать те, которые вам нужны в Python.

...