- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这只发生在 Linux 上(也可能是 OS X,无法测试 atm),在 Windows 上工作正常。
我有一个 wx.ProgressDialog 是用主线程生成的。我将工作发送到另一个线程,它会定期回调主线程中的回调函数,该回调函数将更新 ProgressDialog 或在工作结束时销毁它。但是,发生这种情况时,我会在 Linux 上收到一条有趣的消息:
(python:12728): Gtk-CRITICAL **: IA__gtk_window_set_modal: 断言 'GTK_IS_WINDOW (window)' 失败
对话框确实关闭了,但如果我尝试再次生成它,它看起来已经快完成了。有时段错误也会跟随此消息。
我在这里尝试用精简版模拟它:
import wxversion
wxversion.select("2.8")
import wx
import sys
import threading
MAX_COUNT = 100
## This class is in a different area of the codebase and
class WorkerThread(threading.Thread):
def __init__(self, callback):
threading.Thread.__init__(self)
self.callback = callback
def run(self):
# simulate work done. IRL, this calls another function in another
# area of the codebase. This function would generate an XML document,
# which loops through a list of items and creates a set of elements for
# each item, calling back after each item. Here, we simply set up a for
# loop and simulate work with wx.MilliSleep
for i in xrange(MAX_COUNT):
print i
wx.MilliSleep(30)
wx.CallAfter(self.callback, i)
# Send done signal to GUI
wx.CallAfter(self.callback, -1)
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(350,200))
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
m_btn = wx.Button(panel, wx.ID_ANY, "Run Stuff")
m_btn.Bind(wx.EVT_BUTTON, self.OnRunButton)
box.Add(m_btn, 0, wx.ALL, 10)
panel.SetSizer(box)
panel.Layout()
def OnRunButton(self, event):
self.progressDialog = wx.ProgressDialog("Doing work",
"Doing Work",
maximum=MAX_COUNT, parent=self,
style=wx.PD_APP_MODAL | wx.PD_ELAPSED_TIME)
self.worker(self.threadCallback)
self.progressDialog.ShowModal()
def worker(self, callback):
# This bit is in another part of the codebase originally. In the test,
# I could have added it to OnRunButton, but I wanted function calls to
# be similar between test and actual code
thread = WorkerThread(callback)
thread.start()
def threadCallback(self, info):
# We update based on position, or destroy if we get a -1
if info == -1:
self.progressDialog.Destroy()
else:
self.progressDialog.Update(info)
app = wx.App(redirect=False)
top = Frame("ProgressDialog Test")
top.Show()
app.MainLoop()
(我们选择 2.8,但理想情况下,任何修复都应该在 2.8 和 3.0 中都有效。实际上,由于 3.0 构建错误,我无法在 linux 3.0 中对其进行测试)
这很好地说明了问题:在 Windows 中工作正常,但当它试图破坏进度对话框时出现段错误。但是,我无法获得显示 GTK_IS_WINDOW
我尝试寻找解决方案。我读到这可能是由于工作线程完成得太快,因此在 GUI 的队列中留下了一些消息。我不确定我是否完全理解这一点(从来没有掌握产量和消息等),但我认为这意味着当工作人员处于 100% 时,ProgressDialog(变慢)可能只会在75%,还有额外的 25% 的消息可用于“更新”GUI,但会被销毁。
我想澄清一下我的理解是否正确。
此外,我相信 .Hide()
可以解决问题,但我想改为销毁它,因为这是正确的做法。
无论如何,我们将不胜感激。 =)
最佳答案
我试过你的代码,也尝试过许多修改来解决这个问题,但都失败了。无论如何,我已经创建了以下 wxPython 脚本来实现您的目的,请参见下文:
import wxversion
wxversion.select("2.8") # version 3.0 works, too.
import wx
import sys
import threading
import time
MAX_COUNT = 200
class WorkerThread(threading.Thread):
def __init__(self, target, countNum):
threading.Thread.__init__(self, target = target)
self.setDaemon(True)
self.cnt = countNum
self.target = target
self.pb = self.target.pb
def run(self):
for i in xrange(self.cnt):
print i+1
wx.MilliSleep(50)
wx.CallAfter(self.pb.SetValue, i+1)
wx.CallAfter(self.target.MakeModal, False)
wx.CallAfter(self.target.Close)
class ProgressBarFrame(wx.Frame):
def __init__(self, parent, title, range = 100) :
wx.Frame.__init__(self, parent = parent, title = title)
self.range = range
self.createProgressbar()
self.SetMinSize((400, 10))
self.Centre()
self.Show()
self.t0 = time.time()
self.elapsed_time_timer.Start(1000)
def createProgressbar(self):
self.pb = wx.Gauge(self)
self.pb.SetRange(range = self.range)
self.elapsed_time_st = wx.StaticText(self, label = 'Elapsed Time:')
self.elapsed_time_val = wx.StaticText(self, label = '00:00:00')
vbox_main = wx.BoxSizer(wx.VERTICAL)
hbox_time = wx.BoxSizer(wx.HORIZONTAL)
hbox_time.Add(self.elapsed_time_st, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.ALL, 5)
hbox_time.Add(self.elapsed_time_val, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.ALL, 5)
vbox_main.Add(self.pb, 0, wx.EXPAND | wx.ALL, 5)
vbox_main.Add(hbox_time, 0, wx.EXPAND | wx.ALL, 5)
self.SetSizerAndFit(vbox_main)
self.elapsed_time_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.onTickTimer, self.elapsed_time_timer)
def onTickTimer(self, event):
fmt='%H:%M:%S'
self.elapsed_time_val.SetLabel(time.strftime(fmt, time.gmtime(time.time()-self.t0)))
class Frame(wx.Frame):
def __init__(self, title):
wx.Frame.__init__(self, None, title=title, pos=(150,150), size=(350,200))
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)
m_btn = wx.Button(panel, wx.ID_ANY, "Run Stuff")
self.Bind(wx.EVT_BUTTON, self.OnRunButton, m_btn)
box.Add(m_btn, 0, wx.ALL, 10)
panel.SetSizer(box)
def OnRunButton(self, event):
self.progressbar = ProgressBarFrame(self, 'Working Processing', MAX_COUNT)
self.progressbar.MakeModal(True)
worker = WorkerThread(self.progressbar, MAX_COUNT)
worker.start()
app = wx.App(redirect=False)
top = Frame("ProgressDialog Test")
top.Show()
app.MainLoop()
我正在使用 wx.Gauge
做 wx.ProgressDialog
做的事情,还有一个额外的 wx.Timer
来显示耗时。 MakeModal()
方法用于模仿 ShowModal
效果,这是 Dialog
显示的默认样式,不要忘记释放模态状态MakeModal(False)
否则框架将被卡住。您可以在 ProgressBarFrame
类中添加更多内容。
我认为段错误可能是由事件调用引起的,特别是当涉及多线程
问题时,也许仔细检查wx.ProgressDialog
类会显示一些线索。
关于python - wx.ProgressDialog 在被销毁时导致段错误和/或 GTK_IS_WINDOW 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30959844/
当用户点击登录按钮时,我想在我的应用程序中使用 ProgressDialog。我遇到的问题是未找到 ProgressDialog - AS 中的红色文本。我错过了什么图书馆吗? 渐变 compile
我使用进度条创建了自定义进度对话框,但自定义进度对话框中的进度消息没有更新 最佳答案 您可以使用 ProgressBar实现相同的行为进度对话框 CustomProgressBar progressB
给出下面的代码。我想将标题“请等待调用被激活”转换为印地语(我在 Assets 文件夹中提供的字体).. public ShakeEventsListener(Context context, OnS
当我的设备是 4.4.4 时,我的 ProgressDialog 工作正常,我最近没有使用这个应用程序,同时设备升级到 Lillipop。我不确定这是否对这个问题造成了任何影响,只是提一下。 问题 1
ProgressDialog 在我的代码中添加 progressDialog.dismiss() 方法时无法显示 我还尝试添加Thread.sleep(),以便它的执行将 hibernate 一段时间
我只是想创建一个旋转的进度对话框。没有文字,没有边框,没有背景。只是一个旋转的通知,轻轻地位于内容顶部的屏幕中心。 我在创建这个自定义对话框时看到了两个不同的 Stack Overflow 问题。 他
我的意思是,ProgressDialog 静态方法 show() 的返回值与该类实例的非静态方法 show 之间有什么区别? 有什么理由选择这种策略 ProgressDialog pd = new P
我在进程运行时使用 ProgressDialog 时遇到问题。我已经尝试了所有可能的不正确方法,并查看了许多网站,这些网站提供了我正在尝试做的事情的示例,但是,我仍然遇到了线程在 ProgressDi
我开发了一个 Flutter 应用程序,我使用了 ProgressDialog小部件 ( progress_dialog: ^1.2.0 )。首先,我展示了 ProgressDialog小部件和一些代
在应用程序中创建ProgressDialog时,出现BadTokenException错误。我尝试阅读有关该问题的几篇文章,但我仍然无法真正弄清这是什么原因。单击按钮后,我调用对话框函数。 p
以下是我的代码: public void onClick(View view) { dialog=new ProgressDialog(view.getContext());
我有一个进度对话框,可以工作,但不符合我的外部需求: 我想把它做成这样: 我尝试过的: 1 - 主题化(仅使用样式和样式+主题方法),如此处所述 结果很糟糕(我在对话框周围有一个相同的蓝色边框颜色和标
我正在尝试从互联网获取数据,解析它,然后将数据显示给用户。该操作通常需要 3 秒左右,我希望旋转进度对话框显示一条消息,说明我正在加载数据。问题是 ProgressDialog 仅在加载即将完成时才显
我制作了一个食谱应用程序,我一直在解决一些问题,因为我无法运行该应用程序,但似乎每次修复错误时都会出现另一个错误,我的项目无法解决方法解雇()我不知道该怎么办,我已经根据 Youtube channe
我想从外部类中显示当前 Activity 的 ProgressDialog,而不是将变量传递到外部类或像其他已回答的问题一样使用静态变量。是否可以?这是一些简单的测试代码,可能有助于说明我想要做什么:
在“onCreate”中,我正在从网络下载数据。下载数据的持续时间为 10 秒。我不想在下载数据时使用 ProgressDialog。这是我的代码,但 ProgressDialog 没有出现: pub
我的应用程序正在从网络服务器加载一些数据。这次我想要一个进度对话框以避免应用程序用户出现黑屏。 Button ok = (Button) findViewById(R.id.ok);
我在我的 android 应用程序中创建了一个 ProgressDialog。但我遇到的问题是在它实际完成工作时停止旋转轮子。这是我的代码。我怎样才能让它在我进行其他工作时不断旋转轮子? button
我能做到: ((Activity) mContext).setProgressBarIndeterminateVisibility(true); 但不是这个: ((Activity) mConte
我想从服务内的线程增加一个进度对话框,我真的很难做到,这是我的代码,请帮助我。 我尝试了很多不同的方法,包括 asyncTask(我遇到了上下文问题)并尝试使用静态函数但它无法正常工作,我是 andr
我是一名优秀的程序员,十分优秀!