In a GUI, how to change the mouse to Zoom-to-rectangle - python

I am creating a GUI that revolves around looking at a plot. The users are assumed to be very dense, as per instruction. That being said, I have been told that the default Zoom-to-rectangle button needs to have another button in the toolbar at the top of the program (which I would also program to a shortcut for ease of use).
The problem I am having is I don't know how to turn the mouse into the Zoom-to-rectangle. I don't want it to actually zoom, just change the mouse to where if it is then dragged across the plot while clicking, it will then zoom.
This is hard to explain, so if you need more information than what is provided please ask.

Related

QScrollarea with pictures not scolling

I want to display a film strip of pictures in my GUI. If a small number of pictures they should just show them side by side. If the amount increases it should allow scrolling to the right to reveal other pictures.
I am working inQT designer at the moment to understand the concept. Later I want to generate the code in Python "on the fly" (as pictures/widgets may be added based on user behavior). And I'm using pyqt5
I followed another Stackoverflow question's response and have set up my scroll area, the horizontal layout, and a bunch of buttons that will make the horizontal layout bigger than the scroll area. The buttons would later be replaced with pixmaps once the basic functionality is given.
I did expect this generates the scrollbar behavior but it does not. I can force to show the horizontal scrollbar to show but it does not let me scroll.
I tried to look up all the settings for the Scrollarea but nothing (obvious to me) is blocking the scroll bar behavior.
Any clues where I got it wrong?

Tkinter - Adjusting widgets

I'm recently getting into Tkinter. Today I needed to create a scale, which has values snap to the left mouse button click. The standard seems to be, that it snaps to the right button.
Anyways, I found an answer:
Force TkInter Scale slider to snap to mouse
My question is: Where can I find documentation of the "Scale" class, or any other class, so I can make such adjustments myself in the future?
I tried my best to contact the user who provided the answer and ask him instead. But the terrible and deliberate design choices of this site do not allow that.

Resizing an icon doesn't show on GUI

I am trying to make my GUI icon go bigger.
I tried this:
MainWindow.setWindowIcon(QtGui.QIcon('Logo1.png'))
MainWindow.setIconSize(QtCore.QSize(128,128))
When 'Logo1.png' is 128x128
When I change numbers SetIconSize line, like this:
MainWindow.setIconSize(QtCore.QSize(500,500))
It doesn't show on my GUI.
My questions are:
Does this happen because I need my logo to be smaller something like 28X28?
If I need a specific size, what size is it and how do I make my logo this size?
Even if I do need a specific size, why wont setIconSize change my icon size?
The iconSize property documentation of QMainWindow explains that:
[The] size of toolbar icons in this mainwindow.
As you can see, it has nothing to do with the windowIcon.
It is up to the underlying OS and its window manager to decide the size of the icon, whether its shown in the window decoration (tipically in the title bar), the task manager/window switcher or anything else, and you don't have any control over it through Qt.
The only "exception" is when drawing client-side windows: windows for which the whole decoration is drawn by the program (the title bar with its system buttons and icon, the frame around the window, etc.).
That is, though, something that is usually discouraged as it's hard to achieve without facing various difficulties (both with drawing and interaction); it also makes the window appearance inconsistent with the whole system and could also create issues with accessibility for visually impaired people.

wx.lib.EVT_COLOURSELECT interfering with wx.lib.FloatCanvas.EVT_MOUSEWHEEL

The Problem:
It seems like one event is disabling another event. Before calling event B, event A works just fine. After event B fires, event A no longer works. Both events are custom ones that people made for their wxPython libraries (FloatCanvas and ColourSelect). I'd like to trace the generated events to make sure that, after event B, event A is still being fired (but perhaps not triggering the handler code?)
The Details:
I have a wxPython app where I create a wx.Panel object with two child items - a plot and a legend. This top level panel handles the majority of the events.
The plot is a wx.Panel object with a single wx.lib.FloatCanvas.FloatCanvas canvas in it.
The legend is a wx.Panel with multiple wx.StaticText and wx.lib.colourselect.ColourSelect objects in it (I'm plotting discrete data points).
On the plot, I bind FloatCanvas.EVT_MOUSEWHEEL to my zoom in/out function. On the legend, I bind the wx.lib.colourselect.EVT_COLOURSELECT event to my update_colors function which then sends the event to the parent panel via wx.PostEvent(event).
The parent panel then receives EVT_COLOURSELECT from the child and executes code that changes the colors of my plots.
Source Code:
I haven't had time to write a small sample that demo's the problem, but you can see the problem by running the source code:
https://github.com/dougthor42/wafer_map
Run the wm_app.py file and then go through the following test steps.
Testing Steps:
Scroll/zoom in and out - works just fine
Change a plot color (fires EVT_COLOURSELECT). If you're testing with the source code you do this by clicking on a legend color box and choosing a new color.
Attempt to zoom in and out again. Doesn't work!
Verify that all other events (key down, click-and-drag, mouse move) all work.
Things I've Tried:
Obviously these didn't work or else I wouldn't be here :-P
Unbinding the mousewheel event and rebinding it when the top level panel receives the event from the child.
Completely disabling the handlers for EVT_COLOURSELECT in both the parent panel and the legend.
I thought that perhaps there was something going on in my handlers. Turns out, just
triggering EVT_COLOURSELECT causes the EVT_MOUSEWHEEL to stop working.
Changing FloatCanvas.EVT_MOUSEWHEEL to some other event, for example FloatCanvas.EVT_RIGHT_DOWN
This does actually work! I loose the 'speed' info from the mouse wheel, but right-clicking
before and after step 2 both work.
Seems to indicate that it's an issue with the mouse scroll event specifically.
Has anyone had a problem where events interfere with each other?
It turns out that there wasn't any interference with events - at least not the events that I mentioned.
After a ton of fiddling and attempts at making a bare-bones version that still demonstrated the problem (which I was unsuccessful at doing), I figured out the root cause. Sadly, I did not figure out a workaround.
The Problem:
My plot wx.Panel was binding wx.MOUSE_LEFT_DOWN. It seems that this was preventing the parent wx.Frame window from giving focus to the Panel that held the plot and the legend.
The Solution:
I removed the bind to wx.EVT_LEFT_DOWN and that seems to fix the underlying issue. However, this is still not the ideal case because it causes two other problems:
I can no longer use my left mouse button on the plot. Not a big deal, I guess, because I can always bind right-mouse.
A user must first left-click on the plot area to give it focus before the mouse scroll or any keyboard shortcuts will work. This doesn't necessarily stem from not binding wx.EVT_LEFT_DOWN, but rather (I believe), from something that Windows does. See Focus-follows-mouse in wxPython? for a bit more info.
Failed Workaround:
I tried a workaround: adding code that sends the wx.EVT_LEFT_DOWN event to the parent but either that still didn't work or I was doing it wrong. Here's the left-click event handler that I tried:
def left_click(self, event):
print("left click!")
parent = wx.GetTopLevelParent()
wx.PostEvent(self.parent, event)
So anyway, this question is kinda solved. Hopefully what I've got here helps someone else out.

pygtk window with box that ignores all X(mouse)events (passes them through)

I'd like to do the following: Create a fullscreen, always on top pygtk window with a webkit widget displaying some html, but with a box that is completely transparent, so that the windows below are visible. (This seems to be possible: Is it possible to render web content over a clear background using WebKit?)
What I'd like is to (sometimes) pass all mouse events that occur in the transparent box down to the windows below my application's window, so that I can interact with them normally. So not just visually transparent, but also transparent to mouse events.
Theoretically, I suppose I could catch all events I am interested in with a pygtk Eventbox, find the window directly below mine with wnck, and pass this event to it with python-xlib.
This doesn't exactly seem like the most elegant solution; is there a better way?
Forwarding the events won't work well as you guessed; it creates a lot of race conditions, and some apps will ignore stuff from XSendEvent anyway.
What you can do is set the input shape mask. See http://www.x.org/releases/current/doc/xextproto/shape.html and then look at XFixesSetWindowShapeRegion() in /usr/include/X11/extensions/Xfixes.h which lets you specify a shape "kind" (here you want ShapeInput).
Something like:
XRectangle rect;
XserverRegion region = XFixesCreateRegion(display, &rect, 1);
XFixesSetWindowShapeRegion(display, window, ShapeInput, 0, 0, region);
XFixesDestroyRegion(display, region);
The ability to set ShapeInput is "only" 5-6 years old so if you care about really crappy old versions of X11, you might be hosed.

Categories

Resources