wxPython scrollbar doesn't stick - python

I've been playing with this cookbook example to make a scrollable matplotlib plot with wxPython. However, when I run this code on my Windows 7 machine at work, the scrollbar doesn't seem to work properly. In particular, if I click and drag it to a position, it does update the plot, but then the scrollbar moves back its starting position, instead of staying put. I'm curious if anyone has an idea what's going on here. FWIW, this code worked fine when I ran it on my Linux Mint 14 machine at home.
Right now, I'm trying to fix it by using a wx.ScrolledWindow or a wx.lib.scrolledpanel instead of adding the scrollbar directly to the canvas as in the example. I was also considering using a slider instead of a scrollbar
Thanks

From Programing Windows, Fifth Edition (emphasis mine)...
When you use scroll bars within your program, you share responsibility
with Windows for maintaining the scroll bars and updating the position
of the scroll bar thumb. These are Windows' responsibilities for
scroll bars:
Handle all processing of mouse messages to the scroll bar.
Provide a reverse-video "flash" when the user clicks the scroll bar.
Move the thumb as the user drags the thumb within the scroll bar.
Send scroll bar messages to the window procedure of the window containing the scroll bar.
These are the responsibilities of your program:
Initialize the range and position of the scroll bar.
Process the scroll bar messages to the window procedure.
Update the position of the scroll bar thumb.
Change the contents of the client area in response to a change in the scroll bar.
...so somewhere in OnScrollEvt() method, you'll need call SetScrollPos() with something like...
self.canvas.SetScrollPos(wx.HORIZONTAL, event.GetPosition(), True)

Related

Anchor button at the bottom of the screen in Dear PyGui

I'm writing a file management and config file editing app in Python 3.10 with Dear PyGui as the GUI library. I would like to place a group at the bottom of the window so it:
Stays at the same place when the rest of the content in the window changes
Stays at the same place relative to the lower left (or right) screen corner when the user changes the size of the viewport
I know how to do 1, I can just use pos=(10, dpg.get_viewport_height()-75).
I don't know how to do 2. The above seems to do it upon launch and if you don't resize the viewport, but it doesn't actually anchor them to that relative spot as the window size changes:
To anchor the group to the bottom, you need to update its position on the window resize. Dear PyGui has a callback that fires every time the window is resized: dpg.set_viewport_resize_callback(update) where update is a function that, in this case, runs dpg.set_item_pos("bottom_buttons", (10, dpg.get_viewport_height()-75)). This will keep the buttons positioned at the bottom of the screen.
There might be a better way to do this, and doing it this way might have consequences for overlapping content later on, but it's the easiest way to implement it that I have tried.

Python GTK 3 Popover off window?

So basically I have a window thats just a vertical list of buttons. I want to create a dropdown menu that goes off to the side without changing the size of the window. I am trying to do this with popover, but now I have the problem where my popover gets cut off by the window. Is there a way I can make it bleed past the window boundaries?
Popovers don't go wider than the parent window. You could have a try at a GtkMenu. They are allowed to go wider than the window, up to the width of the monitor.

Tkinter application topmost, even over fullscreen

I'm using tkinter on Ubuntu.
I'd like my application to be on top of the screen, all the time. I'm aware of, and am currently using, wm_attributes("-topmost", 1). I've discovered that this is equal to right clicking on the menu bar of an application and selecting 'Always On Top', which works fine for most applications. However, this doesn't work when full-screen applications are launched (specifically, TF2). In such cases, my widget lies behind the game.
I'm also aware of overrideredirect(True), and this stays on top of the game even over full-screen, but this is not viable as the menu bar and being able to move the window are central to my application.
Is there a way to have tkinter remain on top of every application, including those that are full-screen? Basically the functionality of overrideredirect, but keeping the menu bar and the ability to move the window.

Focus-follows-mouse in wxPython?

I'm developing an application that contains a number of panes. See the screenshot:
The left settings pane is a wx.ScrolledPanel that contains a number of wx.Panels.
The top events pane is a wx.grid.Grid.
The bottom data pane is a wx.Panel that contains a wx.grid.Grid.
The middle plot pane is a wx.Panel containing an enthought chaco plot.
The right detector pane is a wx.Panel.
I would like to implement focus follows mouse so that when I move my mouse over the plot I can immediately zoom in or out using my scroll wheel without first clicking on the plot to give it the focus.
Similarly when I move my mouse over the left settings , the top events or the bottom data panes I would like to be able to immediately scroll the window using the scroll wheel without first clicking on the window.
Currently I defined a function:
def focusFollowsMouse(window):
window.Bind(wx.EVT_ENTER_WINDOW, lambda event: window.SetFocus())
I would like to apply this function only on the four top-level panes: plot, settings, events and data.
However I need to call this function for each sub-panel or control in each of the top-level panes to get this to work. For example I need to apply this function individually to the Measurement Settings, Analysis Parameters, View Settings etc. panels.
Most likely the EVT_ENTER_WINDOW event is not propagated to parent windows.
Is there a way to get this to work without applying focusFollowsMouse to each and every sub-panel or control?
Thanks
This is Windows' behaviour - it works as you expect under GTK. Personally, I'd leave your app as it is, for consistency with other Windows applications, and install WizMouse

Can you auto hide frames/dialogs using wxPython?

I would like to create an application that has 3-4 frames (or windows) where each frame is attached/positioned to a side of the screen (like a task bar). When a frame is inactive I would like it to auto hide (just like the Windows task bar does; or the dock in OSX). When I move my mouse pointer to the position on the edge of the screen where the frame is hidden, I would like it to come back into focus.
The application is written in Python (using wxPython for the basic GUI aspects). Does anyone know how to do this in Python? I'm guessing it's probably OS dependent? If so, I'd like to focus on Windows first.
I don't do GUI programming very often so my apologies if this makes no sense at all.
As far as I know, there's nothing built in for this.
When the window is hidden, do you want it completely invisible or can a border of a few pixels be showing? That would be an easy way to get a mouse hover event. Otherwise you might have to use something like pyHook to get system-wide mouse events to know when to expand your window.
The events EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW might also be useful here to know when the user has entered/left the window so you can expand/collapse it.
Expanding/collapsing can just be done by showing/hiding windows or resizing them. Standard window functions, nothing fancy.
By the way, you might want to use wx.ClientDisplayRect to figure out where to position your window. That will give you a rectangle of the desktop that does NOT include the task bar or any other toolbars the user has, assuming you want to avoid overlapping with those things.
Personally, I would combine the EVT_ENTER_WINDOW and EVT_LEAVE_WINDOW that FogleBird mentioned with a wx.Timer. Then whenever it the frame or dialog is inactive for x seconds, you would just call its Hide() method.
I think you could easily just make a window that is the same size as the desktop then do some while looping for an inactivity variable based on mouse position, then thread off a timer for loop for the 4 inactivity variables. I'd personally design it so that when they reach 0 from 15, they change size and position to become tabular and create a button on them to reactivate. lots of technical work on this one, but easily done if you figure it out

Categories