如何覆盖“取消"ProgressDialog 的按钮事件? [英] How to override the "Cancel" button event of a ProgressDialog?
问题描述
ProgressDialog
类允许传递选项 wx.PD_CAN_ABORT
在对话框中添加了一个取消"按钮.我需要重新绑定绑定到此的事件按钮,使其 Destroy()
对话框而不是仅仅进行下一次调用to Update() [to] return False",如该类的文档所述.
The ProgressDialog
class allows passing the option wx.PD_CAN_ABORT
which
adds a "Cancel" button to the dialog. I need to rebind the event bound to this
button, to make it Destroy()
the dialog instead of just "making the next call
to Update() [to] return False" as the class's documentation describes.
class PortScanProgressDialog(object):
"""Dialog showing progress of the port scan."""
def __init__(self):
self.dialog = wx.ProgressDialog(
"COM Port Scan",
PORT_SCAN_DLG_MSG,
MAX_COM_PORT,
style=wx.PD_CAN_ABORT | wx.PD_AUTO_HIDE)
def get_available_ports(self):
"""Get list of connectable COM ports.
:return: List of ports that e.g. exist, are not already open,
that we have permission to open, etc.
:rtype: list of str
"""
com_list = []
keep_going = True
progress_count = 0
for port_num in range(MIN_COM_PORT, MAX_COM_PORT + 1):
if not keep_going:
break
port_str = "COM{}".format(port_num)
try:
# Check if the port is connectable by attempting to open
# it.
t_port = Win32Serial(
port_str, COMPATIBLE_BAUDRATE,
bytesize=SerialThread.BYTESIZE,
parity=SerialThread.PARITY,
stopbits=SerialThread.STOPBITS, timeout=4)
t_port.close()
com_list.append(port_str)
finally:
progress_count += 1
# This returns a tuple with 2 values, the first of which
# indicates if progress should continue or stop--as in
# the case of all ports having been scanned or the
# "Cancel" button being pressed.
keep_going = self.dialog.Update(progress_count, msg)[0]
return com_list
这个类在其他地方以这种方式使用:
This class is used elsewhere in this fashion:
# Scan for available ports.
port_scan_dlg = PortScanProgressDialog()
ports = port_scan_dlg.get_available_ports()
port_scan_dlg.dialog.Destroy()
当 get_available_ports()
中发生未处理的异常时,进度对话框将保持打开状态(这是预期的行为),但问题是当我点击取消"按钮是灰色的并且窗口没有关闭(点击X"也无法关闭窗口).
When an unhandled exception occurs in get_available_ports()
the progress
dialog will stay open (which is expected behaviour), but the problem is that
when I hit "Cancel" the button is greyed and the window is not closed (clicking
"X" also fails to close the window).
我正在尝试将取消"按钮重新绑定到 Destroy()
的方法对话.我该怎么做?
I'm trying to re-bind the "Cancel" button to a method that Destroy()
s the
dialog. How can I do this?
我知道这个解决方法,但我认为它更干净使用 ProgressDialog
并根据我的需要对其进行修改.
I'm aware of this workaround, but I think it's cleaner to use ProgressDialog
and modify it to my needs.
推荐答案
取消按钮未直接在此小部件中公开.您可以使用对话框的 GetChildren
方法访问它.这是一种方法:
The Cancel button is not exposed directly in this widget. You can get to it using the dialog's GetChildren
method. Here's one way to do it:
import wx
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
b = wx.Button(self, -1, "Create and Show a ProgressDialog", (50,50))
self.Bind(wx.EVT_BUTTON, self.OnButton, b)
def OnButton(self, evt):
max = 80
dlg = wx.ProgressDialog("Progress dialog example",
"An informative message",
maximum = max,
parent=self,
style = wx.PD_CAN_ABORT
| wx.PD_APP_MODAL
| wx.PD_ELAPSED_TIME
#| wx.PD_ESTIMATED_TIME
| wx.PD_REMAINING_TIME
)
for child in dlg.GetChildren():
if isinstance(child, wx.Button):
cancel_function = lambda evt, parent=dlg: self.onClose(evt, parent)
child.Bind(wx.EVT_BUTTON, cancel_function)
keepGoing = True
count = 0
while keepGoing and count < max:
count += 1
wx.MilliSleep(250) # simulate some time-consuming thing...
if count >= max / 2:
(keepGoing, skip) = dlg.Update(count, "Half-time!")
else:
(keepGoing, skip) = dlg.Update(count)
dlg.Destroy()
#----------------------------------------------------------------------
def onClose(self, event, dialog):
""""""
print "Closing dialog!"
########################################################################
class MyFrame(wx.Frame):
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
wx.Frame.__init__(self, None, title='Progress')
panel = TestPanel(self)
self.Show()
if __name__ == '__main__':
app = wx.App(False)
frame = MyFrame()
app.MainLoop()
这是基于此特定对话框的 wxPython 演示示例.根据您的平台,您将获得本机小部件(如果存在),否则您将获得 wx.GenericProgressDialog
.我怀疑本机小部件根本不允许您访问取消"按钮,但我不确定.
This is based on the wxPython demo example of this particular dialog. Depending on your platform, you will get the native widget if it exists, otherwise you'll get wx.GenericProgressDialog
. I suspect the native widget won't allow you to access the Cancel button at all, but I'm not sure.
这篇关于如何覆盖“取消"ProgressDialog 的按钮事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!