强制重新绘制 wxPython 窗口、wxmpl 绘图

发布于 2024-11-17 00:52:34 字数 724 浏览 2 评论 0原文

我在刷新 wxPython 窗口时遇到问题。它当前正在使用 wxmpl 绘制图表,该图表可以缩放、平移等。有时,用户可能会绘制大量数据并放大一小部分,这可能会导致其“冻结”。我的意思是绘图本身没有更新,并且轴标签是在彼此之上绘制的。它正在修改绘图,只是没有正确显示更新的信息。如果调整窗口大小,绘图将正确重新绘制。

我花费了大量的时间挖掘 wx、wxmpl 和 matplotlib 的源代码和文档...我想出的最佳解决方案是调整窗口大小以强制重新绘制(从而正确显示更新的绘图) 。

# All of these fail - displays the same, incorrect plot
# (view is a wxmpl.PlotPanel object, which inherits from wx.Window among other things)
view.Refresh()
view.Update()
view.draw()

# This works, but is clearly less than ideal
view.SetSize((view.GetSize().width, view.GetSize().height+1))
view.SetSize((view.GetSize().width, view.GetSize().height-1))

必须有一个更好的方法 - 我真正想知道的是 wx.Window.SetSize 是如何重绘窗口的,并且只需调用它即可。或者,我是否在某个地方错过了另一种方法?

I'm having problems getting my wxPython window to refresh. It's currently plotting a graph using wxmpl which can be zoomed, panned, etc. On occasion the user may plot a large amount of data and zoom in on a small portion, which can cause it to 'freeze up'. By that I mean the plot itself is not updated, and the axis labels are drawn on top of each other. It is modifying the plot, just not displaying the updated info correctly. If you resize the window the plot is redrawn correctly.

I've spend an inordinate amount of time digging through source code and documentation for wx, wxmpl, and matplotlib... The best solution I've come up with is resizing the window to force a repaint (thus displaying the updated plot correctly).

# All of these fail - displays the same, incorrect plot
# (view is a wxmpl.PlotPanel object, which inherits from wx.Window among other things)
view.Refresh()
view.Update()
view.draw()

# This works, but is clearly less than ideal
view.SetSize((view.GetSize().width, view.GetSize().height+1))
view.SetSize((view.GetSize().width, view.GetSize().height-1))

There's got to be a better way - what I really want to know is what wx.Window.SetSize does to redraw the window, and just call that instead. Or, is there another method that I missed somewhere?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

望喜 2024-11-24 00:52:34

panel.Layout() 命令是一个很好的选择,因为它与调整窗口大小时调用的方法完全相同。我在刷新和更新方法方面也遇到了麻烦。当这两个失败时,布局似乎有效。

The panel.Layout() command is a great option because it is exactly the same method that is called when you resize your window. I also had trouble with the refresh and update methods. Layout seems to work when those two fail.

伴我老 2024-11-24 00:52:34

如果您无法将其放置在其他位置,您可以尝试

wx.Yield()

使用 RefreshUpdate 来代替。

If you can't place it anywhere else, you could try

wx.Yield()

instead of Refresh or Update.

自演自醉 2024-11-24 00:52:34

我还会尝试在 PlotPanel 上显示(False),然后显示(True)。

I would also try Show(False) and then Show(True) on the PlotPanel.

挽容 2024-11-24 00:52:34

在计算成本较高的应用程序中,您预计计算时间超过 0.1 秒,并且可能有一些用户输入,通常不建议在 GUI 线程中进行这些密集的绘制。

不知道您的具体情况,但如果您将所有耗时的任务(无论是计算、图像调整(例如缩放))移至非 GUI 线程,则一般方法。只要一个普通的 Python 线程就可以了,一旦你完成了一个长的部分,你就可以刷新你的 GUI。当然,在计算过程中,显示​​某种“等待”标志将是用户友好的。同时禁用其他控件,因此无聊的用户将无法在计算中途更改任何内容。

自从我早期使用 Java 和后来使用 Python 以来,我就一直被这个问题困扰,主要是与网络操作有关(永远不应该在 GUI 线程中)。

如果是图像调整(或图形生成),需要花费很多时间,后台线程可以在wxMemoryDC中准备图像,然后wxDC::Blit到您选择的窗口。我不知道这是否可以用您的组件 wxmpl.PlotPanel 来完成,所以您必须对此进行研究。

In a computational expensive application, where you are expecting something to be calculated for over 0.1 sec and probably have some user input it is not recommended usually to make those intense drawing in the GUI thread.

Not aware of your specific situation, but general approach if that you move all time consuming tasks (be it computation, image adjustment (e.g. scaling)) to the non GUI thread. Just a normal Python thread is fine, and once you have an long part complete, you refresh your GUI. During computation of course it would be a user friendly to display some sort of "waiting" sign. Also disable other controls, so bored user will not be able to change anything midway to your computation.

I was stuck with that issue since my early days with Java and later with Python, mostly in connection to network operations (which NEVER should be in GUI thread).

In case it is image adjusment (or graphics generation), which takes much time, background thread can prepare image in wxMemoryDC and then wxDC::Blit it to the window of your choice. I am not aware if this can be done with your component wxmpl.PlotPanel, so you will have to research this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文