6,210
社区成员




python写windows的小工具相比Java要方便很多,无论是打包成exe的便捷性,还是体积。近期初步学了下Python,在用到wxpython的时候有一个疑问,那就是调用Frame类构造函数第一个入参必须要有值,否则会报错。下面是Frame里的一段注释
"""
Frame()
Frame(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr)
A frame is a window whose size and position can (usually) be changed
by the user.
"""
这里不难理解,parent 是一个位置参数,所以调用时必须要有实参,其他参数则有默认参数,可以不传,这是报错的原因所在。
我的疑问是,Frame的构造函数不是以下这个吗
def __init__(self, parent=None, id=None, title=None, pos=None, size=None, style=None, name=None): # real signature unknown; restored from __doc__ with multiple overloads
pass
那上面的注释提到的
Frame(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr)
是在哪里设置的默认值?我理解这段代码不应该写在构造方法__init__里面吗(如果是在重写的构造函数里,我也没找到,是我找的方法不对,还是重写的构造也没这个写法?),即
def __init__(self, parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr): # real signature unknown; restored from __doc__ with multiple overloads
pass
这样我在调用Frame构造函数的时候除了parent其他参数都有默认值。而且我按照Frame的构造方法对它进行调用是会报错的,比如传入name=None,报错信息是: arguments did not match any overloaded call。意思是没有任何重构方法的参数列表符合实参,我的疑问是构造函数不就是这么定义的吗,怎么就不符合了?
# 这里name=None 会报错
super().__init__(None, title="My GUI Application", size=(400, 300), style=wx.DEFAULT_FRAME_STYLE,name=None)
自定义一个类则不会报错,
class User():
def __init__(self, parent=None, id=None, title=None, pos=None, size=None, style=None,
name=None): # real signature unknown; restored from __doc__ with multiple overloads
print(id,title,parent)
# 传pos=None不会报错
user = User(id=234,title='123',pos=None)
以下是demo代码
import wx
class MyFrame(wx.Frame):
def __init__(self):
# 参数列表第一参数没设置会报错
# fr = super().__init__(title="My GUI Application", size=(400, 300))
fr = super().__init__(None, title="My GUI Application", size=(400, 300),style=wx.DEFAULT_FRAME_STYLE)
# 传入name=None会报错
# fr = super().__init__(None, title="My GUI Application", size=(400, 300), style=wx.DEFAULT_FRAME_STYLE,name=None)
# 设置窗口置顶
# self.SetWindowStyle(self.GetWindowStyle() | wx.STAY_ON_TOP)
panel = wx.Panel(self)
label = wx.StaticText(panel, label="Hello, WxPython!", pos=(100, 50))
button = wx.Button(panel, label="Click Me!", pos=(150, 100))
button.Bind(wx.EVT_BUTTON, self.on_button_click)
def on_button_click(self, event):
wx.MessageBox("Button clicked!", "Info", wx.OK | wx.ICON_INFORMATION)
if __name__ == '__main__':
app = wx.App()
frame = MyFrame()
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
这里提到的只是Frame类的构造函数问题,也可以引申到其他所有类,如果不理解里面的规则,在用到其他类时,我肯定会对怎么给构造函数传参一脸懵。请Python的大佬们帮忙解答下,谢谢。
您提出了一个非常好的问题。关于 wxPython 中 Frame 类的构造函数确实有一些细节需要注意。
首先,我们来看下 Frame 类的构造函数定义:
def __init__(self, parent=None, id=None, title=None, pos=None, size=None, style=None, name=None):
# 构造函数实现
pass
从这里可以看出,Frame 类的构造函数接受多个参数,其中 parent 参数是必须的,其他参数都有默认值。
现在,我们再看一下您提到的注释:
Frame(parent, id=ID_ANY, title=EmptyString, pos=DefaultPosition, size=DefaultSize, style=DEFAULT_FRAME_STYLE, name=FrameNameStr)
这里提到的是 Frame 类的构造函数签名,而不是实际的 init 方法实现。wxPython 使用的是 C++ 风格的函数签名,在 Python 中转换为方法签名时,默认参数值通常会被省略掉。
所以,在您的代码中使用 super().init() 调用基类构造函数时,第一个参数 parent 是必须的,其他参数则可以使用默认值。
对于您提到的 arguments did not match any overloaded call 错误,这是因为 wxPython 为了支持多种参数组合,会提供多个重载的构造函数。当您传入的参数不符合任何一个重载函数的签名时,就会出现这个错误。
为了避免这种错误,您可以像自定义 User 类那样,明确地定义构造函数的参数列表,并在调用时传入对应的参数。这样就可以确保参数的正确性。
总的来说,在使用 wxPython 等第三方库时,理解其 API 设计的一些细节是很重要的。希望这个解答对您有所帮助。如果还有其他问题,欢迎继续询问。
稍等,我直接帮你问ai
棒棒哒!