What is the best practice to overlay a Phonon.VideoWidget? - python

The last couple of days I have tried to find a working solution to overlay a Phonon.VideoWidget with a simple QLabel. Sadly I wasn't able to find a working solution.
Here is what I have tried:
Parenting. I tried the "normal" parenting stuff addressing the QLabel to the VideoWidget. Result: The label does not show up at all.
QStackedLayout. As suggested here: http://www.qtcentre.org/threads/31490-Overlaying-Widgets-on-top-of-VideoWidget. Result: Label is shown but always behind the video
GraphicsView. I tried a lot here as it looked like the most promising, but at the end the CPU load was just too high so the video did not play back. Setting the view's viewport to QGLWidget did not solve it. Result: Overlay works but video does not play caused by high CPU load.
Subclassing the VideoWidget. As mentioned here: https://wiki.qt.io/Overlay_widget_for_Phonon_VideoWidget. I took the same approach to create the overlay. This works just fine after all, except for the moveEvent. It does not look nice if the label is realigned after moving the widget has finished. Is there a way to update this already when moving VideoWidget?
I really hope someone can help me here (I use PySide but examples in C++ should work as well) or give me a pointer on where to look. Please let me know if I should share some code snippet to reproduce.

The best you can do is creating a new window that floats above your video widget. For example create a parentless QLabel and make sure that it moves in sync with your main window.
label = new QLabel();
label->setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint);
In your QMainWindow subclass, override moveEvent and resizeEvent and do something like:
label->move(mapToGlobal(QPoint(0, height() - label->height())));
This keeps the label in the bottom-left corner, change it to fit your needs.

Related

2d graphics in Python Kivy, advice is needed

I still have been studying world of Kivy and I have encountered with question. I am designing an interface. it has to have an appearance of analog device with arrow and curved scale like old voltmeters were. Just to display a data on the screen. I've tried to use canvas, but I stacked with resizing of window properties. Built canvas object was either connected to specific size in px, or changed location on the screen in wrong way. So, I am curious, maybe here are some others ways to embed objects which were built in another 2d graphics library, I am aware of existence of 3d module vpython and turtle. Maybe we have some more?
Can anybody give me a hint? I would be very grateful
kivy, canvas
view of my prototype
You can use Image widgets combined with Button Behavior or ToggleButton Behavior to make buttons that look like almost any kind of button that you like. And you can make a curved scale as described in this question.

Is there a way to draw in the "background" using turtle?

Is there a way to have an image be created/drawn entirely without the actual Window that usually pops up when starting a turtle script showing up? The reason for this question is that while doing more research into another problem I posted here:
How to properly interact with turtle canvas/screen sizing?
I found that resizing the screen using maximize on the window actually altered what was capture when using .getcanvas() to be saved.
This wouldn't be a problem if I weren't attempting to create large images, larger than my monitors certainly. (around 15000 x 15000 pixels).
Thus I am wondering if there is a way to have the entire drawing process be done in the background. Without a window popping up at all. This way (I would hope at least) my images aren't becoming distorted or incorrectly sized due to buggy window interactions. As an example when I try to create an image this big, even with turtle.tracer(False) set it still flashes for a small amount of time (as the images are large and take time to complete) and while it is 'open' I cannot switch to it, it does not appear on my screen, it only appears on the task bar, which I can hover over and like with other applications 'preview' it without clicking on it, and it does not show there. However the image will be created and saved. But the dimensions are entirely wrong based on the code I used.
For a minimally repeatable example please look to the hyperlink to my related question. The code and subsequent image of that post is directly related to this question. But as the questions are different in nature I decided to create this post asking it.
Any feedback would be greatly appreciated as I cannot find any information in the documentation on how this might be done if it is possible at all. If anyone knows any good resources to directly contact regarding Turtle then that information would be welcomed as well.
I'm not sure if this will help to much but if you set the turtles speed to 0 then there will be no animation and the turtle will draw the picture instantly.
The code would look something like: turtle.speed(0)

Creating a "Fill" command in tk inter

I am pretty new to Python and coding in general. I have been working on a program that is similar in nature to ms paint. So far, I've added the capabilities to create multi-colored rectangles, lines, ovals, and really any polygon.
I've been using the tkinter GUI. I've been wanting to add a fill command, but I'm kind of stuck as to how to start it. My idea for how it would work would be that it would check the color of the pixel the user is currently hovering over, then check up, down, left, and right for the same color in pixels. If it found that, it would change the color of those pixels (I guess by creating a really small rectangle object?). This would theoretically be able to fill an area. But, I really can't find anything on how to access the color of a pixel in tkinter.
I know the location is event.x and event.y for a specific event, but I can't find anything about pixel color. I don't really have any code written for it yet because I am unsure that tkinter can even access the color of a pixel and not just object colors.
Unfortunately, this isn't possible. I did some searching around, and found several other similar questions, but the general idea is that Tkinter does not support such a feature. It makes sense, considering that Tkinter is a GUI library.
I saw a suggestion somewhere, where an idea was proposed to create 1x1 rectangles using the Tkinter Canvas to basically mimic pixels. However, this method eventually leads into performance issues and lagging, so it's not really recommended either.
You may want to try exploring some other libraries to work together with Tkinter. You can keep the Tkinter GUI, but use an image manipulation library or something similar which integrates well with Tkinter, for the actual pixel drawing.

How to draw directly on the screen with wxpython?

I'm using Linux and e17 with composition disabled, and I would like to create a program capable of drawing simple geometrical shapes and text directly onto the screen.
My first thought was to do:
import wx
app = wx.App(False)
s = wx.ScreenDC()
s.Pen = wx.Pen("#FF0000")
s.DrawRectangle(60,60,120,120)
But this wouldn't work, so I replaced the last line with:
for i in range(0,129):
s.DrawRectangle(60,60,120,120)
Which somehow made it work, but it's a hacky solution and to draw lines I need to increase amount of iterations even more.
I think the problem might be with transparency, but have no idea how to solve it.
Any help would be appreciated, thanks.
Do you specify, StartDrawingOnTop anywhere? Otherwise, it seems you might have a transparency issue so you might try setting that explicitly.
I would think you could do this by creating a frame and panel and then call the frame's SetTransparency method to set that. You definitely want to use DCs or something similar like FloatCanvas to do the drawing. Worth a try anyway.

Force repaint of wxPython Window, wxmpl plot

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?
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.
If you can't place it anywhere else, you could try
wx.Yield()
instead of Refresh or Update.
I would also try Show(False) and then Show(True) on the 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.

Categories