我有一个依赖外部配置文件的 wxPython 应用程序。我想提供友好的消息对话框,如果有任何配置错误,就会显示该对话框。我尝试通过将 app.MainLoop() 调用包装在 try/ except 语句中来完成这项工作。
下面的代码适用于我的 MainWindow 框架类中的初始化代码,但不会捕获 MainLoop 中发生的任何异常。我怎样才能捕获这些异常呢?
if __name__ == '__main__':
app = MyApp(0)
try:
MainWindow(None, -1, 'My Cool App')
app.MainLoop()
except ConfigParser.Error, error_message:
messagebox = wx.MessageDialog(None, error_message, 'Configuration Error', wx.OK | wx.ICON_ERROR)
messagebox.ShowModal()
Run Code Online (Sandbox Code Playgroud)
我读过一些关于可以在 wx.App 类中重写的 OnExceptionInMainLoop 方法的内容,但我读到的源代码必须已过时(2004 年),因为 wx.App 似乎不再具有该名称的方法。
编辑:
我需要能够在主循环期间捕获未处理的异常,以便我可以进一步处理它们并将它们显示在错误对话框中,而不是静默传递,并且不终止应用程序。
sys.excepthook 解决方案级别太低,并且与 wxPython 主循环线程不能很好地配合。虽然到另一个答案的链接做了相同的尝试/除了环绕主循环,但由于 wxPython 再次为应用程序/ui 生成了不同的线程,所以它不起作用。
我尝试用谷歌搜索它,并且查看了 wxpython 文档,但我似乎找不到一种方法——你能删除它wx.MessageDialog弹出时(也就是你打电话时.ShowModal())发出的恼人的“错误”蜂鸣声吗? ?
我有一个用 wxglade 制作的应用程序。我添加了一个媒体控件来播放 mp3:s。如果没有媒体控制,应用程序将以 800x600px 的框架启动。但是当我添加媒体控件时,框架非常小。我相信这是因为我没有将其添加到 sizer 中。但我必须这样做吗?无论如何,媒体控件不应该显示任何内容。
所以,我的问题是,如何将媒体控件添加到我的应用程序中,而不会(a)破坏使用 wxglade 更新 gui 的可能性以及(b)失去以正确大小启动的能力?
如果可以的话我不会在# Begin wxglade和之间放置任何东西# End wxglade。因为如果我用 wxglade 更改我的 gui(无论如何根据早期的测试),它就会被破坏。
编辑:我提供的代码片段没有添加任何有趣的内容。我还编辑了问题以使其更加清晰,以便其他有相同问题的人可以找到答案。
考虑下面的代码:
import wx
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.cb1 = wx.CheckBox(self, -1, "CheckBox 1")
self.cb2 = wx.CheckBox(self, -1, "CheckBox 2")
self.cb3 = wx.CheckBox(self, -1, "CheckBox 3")
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.cb1, 0, wx.ADJUST_MINSIZE, 0)
sizer.Add(self.cb2, 0, wx.ADJUST_MINSIZE, 0)
sizer.Add(self.cb3, 0, wx.ADJUST_MINSIZE, 0)
self.SetSizer(sizer)
self.Layout()
self.Bind(wx.EVT_CHECKBOX, self.OnCb1, self.cb1)
self.Bind(wx.EVT_CHECKBOX, self.OnCb2, self.cb2)
def OnCb1(self, evt):
self.cb2.SetValue(evt.IsChecked())
def OnCb2(self, evt):
self.cb3.SetValue(evt.IsChecked())
if __name__ == "__main__":
app = wx.PySimpleApp(0)
frame = MyFrame(None, -1, "")
app.SetTopWindow(frame)
frame.Show()
app.MainLoop()
Run Code Online (Sandbox Code Playgroud)
这里我有 3 个复选框绑定在一起,所以什么cb2 …
我不知道何时何地使用 wx.App 和 PySimpleApp
就像两个代码:
#!/usr/bin/env python
import wx
import wx.py.images as images
class ToolbarFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Toolbars',
size=(300, 200))
panel = wx.Panel(self)
panel.SetBackgroundColour('White')
class App(wx.App):
def OnInit(self):
frame = ToolbarFrame(parent=None, id=-1)
frame.Show()
return True
if __name__ == '__main__':
app = App()
app.MainLoop()
Run Code Online (Sandbox Code Playgroud)
和这段代码:
#!/usr/bin/env python
import wx
class ToolbarFrame(wx.Frame):
def __init__(self, parent, id):
wx.Frame.__init__(self, parent, id, 'Toolbars',
size=(300, 200))
panel = wx.Panel(self)
panel.SetBackgroundColour('White')
if __name__ == '__main__':
app = wx.PySimpleApp()
frame = ToolbarFrame(parent=None, id=-1) …Run Code Online (Sandbox Code Playgroud) 我将一些行放入列表控件中,然后相当快地更新它们 - 通常数据来自总线 - 并且整个列表闪烁很多。阻止它这样做真是太好了。
我尽可能地减少了代码,同时仍然保持我在下面的示例中所做的事情的总体外观。
lisctrl 是在 wx.Notebook 中还是在普通的 wx.Panel 中似乎并不重要,所以我把笔记本留在那里。
我已经开始研究双缓冲,但想看看是否还有其他可以先尝试的方法。
在 Windows 7 上使用 wxPython 2.8.12.1 执行此操作。XP 上也会发生。
import sys
import time
import logging
import wx
from random import randint
UPDATE_MS=10
class CanMsg(object):
def __init__(self, ID, type, len, data=None):
"""Represents a CAN message"""
self.ID=ID # 11/29-bit message identifier
self.MSGTYPE=type # Type of the message
self.LEN=len # Data Length Code of the message (0..8)
if data:
self.DATA=data
else:
self.DATA=[0,]*len
class EmulatorFrame(wx.Frame):
def __init__(self, parent, id, title, pos=wx.DefaultPosition, size=wx.DefaultSize, …Run Code Online (Sandbox Code Playgroud) 我正在使用 PyInstaller (v1.5) 构建一个可执行文件 - 另外,我正在使用 GUI2EXE 来帮助我。我的脚本需要位于工作目录中的图标文件:
icon_file = '\pics\myicon.ico'
Run Code Online (Sandbox Code Playgroud)
当我构建可执行文件时,我希望不必包含“工作目录”,而是将图标文件包含在我的可执行文件中。有没有办法做到这一点?
如果此后没有成功,我想要一个包含我的图标文件的文件(我的可执行文件)。
我还希望对任何图像文件甚至数据文件执行此操作...
谢谢!
我正在尝试在 wxpython 中使用图像作为按钮。我想要的是按钮周围应该只有一个位图,没有其他边框或任何额外的像素。我真的只想捕获位图上的点击,所以也许我不需要实际的按钮。因此不需要“按下”按钮。
我使用带有 Platebutton.PB_STYLE_NOBG 的 PlateButton 的一种选择是,仅当它在没有任何鼠标悬停或单击的情况下显示图像时,该选项才能正常工作。现在,当我悬停按钮时,我想要的是同一图像的阴影图像(只有图像,没有边框或任何东西),但我得到的是图像周围的方形边框。
我的代码:
import wx.lib.platebtn as platebutton
imageButton = platebutton.PlateButton(self._ribbon,wx.ID_NEW, bmp = wx.Bitmap("image.png", wx.BITMAP_TYPE_ANY), pos = (0,0), size = (37,17), style= platebutton.PB_STYLE_DEFAULT | platebutton.PB_STYLE_NOBG)
Run Code Online (Sandbox Code Playgroud) 我正在构建一个应用程序来执行一些图像分析任务。我需要能够进行一些图像操作(即旋转、缩放、更改中心点等),以获得图像的特定部分进行分析。我在 gui 中使用 wxPython,因此显示的图像需要是 wxImage 类型(缩放然后转换为 wxBitmap)。不过,我的图像数据是一个二维浮点数组。为了创建 wxImage,数据需要采用 RGBA 格式。所以,现在,我正在将图像转换为 RGBA 并使用 scipy.interpolate.rotate()(通过裁剪图像进行缩放等)进行旋转,并保存我想要的部分的所有信息。然后,一旦找到该部分,我就使用新找到的参数对原始浮点数组数据执行相同的操作。
因此,问题是,即使使用隔壁邻居 (NDN) 插值(模式 = 0),旋转 RGBA 图像也非常慢(因为图像约为 2000x2000)。当我插入浮点数组(用于分析)时,速度还不错(只要我使用 NDN 或线性)。
那么我的问题是:
任何帮助将不胜感激。谢谢。
在我的程序中,我有一个包含插入子菜单的上下文菜单。我不想为子菜单中的每个选项创建不同的函数,而是想将所有选项绑定到同一个函数。有没有办法让我确定所选项目的标签或 ID,以便我可以将其传递给不同的函数?
编辑:经过一番研究,我找到了函数 GetId(),这就是我想要的,但我仍然需要从 id 中获取标签。我也许可以使用 FindWindowById,它是 wx.Window 的函数,但它只能查看窗口的子窗口。该框架似乎不是子菜单中项目的父级,所以我不能只是这样做frame.FindWindowById(id)。