WxPython custom popup window - python

I am trying to make a custom window that acts like a popup window and closes as it loses its focus (click outside of popup).
I have a frame with several clickable images. If you click one of the images a frame appears. This frame is a base class and its contents (text controls, grids, buttons e.t.c) are replaced depending on what image you clicked. My problem is where and what event I should capture.
I will try to simplify with sample/pseudo code.
class MainFrame(MainFrameDefinition):
# unimportant code
custom_frame_holder = CustomFrame()
for child_panel in self.lots_of_panels:
# add a panel to a map and set
custom_frame_holder.panel = child_panel
class CustomFrame(wx.Frame):
def __init__(self, parent):
# unimportant code
self.panel = # a panel that changes
self.Bind(wx.EVT_KILL_FOCUS, self.lost_focus)
def lost_focus(self, event):
self.Hide()
So what seems to be the officer problem? Well as soon as I click on a control in the CustomFrame, the frame loses its focus and the window will hide.
I have tried to capture EVT_CHILD_FOCUS and then set the focus back to the frame, but then, since the frame has the focus I am unable to write in say a text control.
I have looked at the wxPopup and wxTransientPopup, but they apparently have a bug that doesn't allow radio buttons, which makes them useless to me.
Let me know if I make no sense and I will try to explain better.

Use wxEVT_ACTIVATE for this purpose (probably wx.EVT_ACTIVATE in wxPython).
I think the radio button issue in popup windows was fixed in the trunk.

Related

How to set focus to the old window on button click in PyQt5 Python?

My Current Project is to create a On Screen Keyboard for my personal usage with my personal functionality. I made gui and primary function in PyQt5 with Python. I managed to type the letter on button click with pyautogui.write() method. But the problem is, where I want to type there is no focus. suppose I want to write on chrome's address bar or any other input field on my monitor. when I click on button to type a letter, chrome lost focus. I want to set focus to the old window while press on any button. I searched on google about this but didn't found any answer. How can i set focus to old window? or is there any better way to type on focus lost state?
You should not try to "set the focus back", as it would be almost impossible to know what window had the focus before (and a new window might raise in the meantime). What you should actually do is to prevent your window to get focus at all, thus avoiding it to steal focus from the others.
In order to achieve this, you must set the appropriate window flag (or initialize the widget with it using the flags keyword argument), which for this is Qt.WindowDoesNotAcceptFocus.
Note that you might also want to set the Qt.WindowStaysOnTopHint in order to always keep your window above the others:
class MyKeyboard(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowFlags(
QtCore.Qt.WindowDoesNotAcceptFocus
| QtCore.Qt.WindowStaysOnTopHint
)

Is it possible to see if the file is being dragged over the window in Kivy, Python?

What I want to achieve:
I want to detect the situation when the user is dragging a file over the Kivy app window.
What I already know:
I know how to detect hovering mouse coursor over widgets (with on_mouse_pos), I also know how to detect if a file is dropped onto the window (with on_file_drop).
So, is it possible to see whether the cursor is hovering over the window and "holding" a file? Because then I want to display some prompt (eg. 'Drop HERE'). I hope you get the idea :)
I'm not really sure, because there's this thing with SDL2 (and probably even with old pygame) when the Window just pauses (try some animation or something) when you e.g. drag it with the window decoration (the thing where title and _ O X are). That is the behavior if you do something with the Window directly.
Although, the Window looks like it behaves normally (doesn't pause itself), when you drag file on top of it (I tried with examples/animation/animate.py), to do such thing you'd need to do either the hovering behavior + handling the collisions or bind to mouse_pos.
However, when binding to mouse_pos, it seems like the Window still isn't capable of handling the input from outside and at the same time get mouse properties correctly (I think it's similar to the behavior when you click & drag outside of the Window and Button remains pressed, but this is kind of inversed).
edited animate.py:
class TestApp(App):
def on_mouse_pos(self, win, args):
print args
...
def build(self):
...
from kivy.core.window import Window
Window.bind(mouse_pos=self.on_mouse_pos)
return button
Therefore if you can't get even mouse position when a mouse button is being held, I don't think such an action is possible. You can however make the areas where you want to drop the file already different (e.g. change background) when you'll expect a user to drop the file - a very dirty workaround from UI side for such a problem.
Side note: Kivy should be able to get most (if not all) SDL2 window events via Cython, therefore if you find such event in SDL2 that would make fetching mouse position possible, such action could be performed, feel free to make a feature request in kivy/kivy or make a pull request.

How do you switch between two windows in PyQt?

I want to make a new PyQt window show up and hide the current window when I click a button. After playing around for hours, I haven't found a good way to do this.
When I try to show a new QDialog and hide the current one, the program closes. It works if another window is open. I believe this is because it is viewing the last window as closing and terminates, or maybe the new QDialog is falling off the stack.
My current method involves storing the QDialog as a variable in the current dialog, then showing it and hiding current dialog. This seems like a total hack, though.
Example below:
def _createQuestion(self):
# initialization of the UI and everything goes on in the constructor
self.dialog = QuestionBanks()
self.dialog.show()
self.hide()
Is there a better way of switching a single window to a distinct different single window in PyQt4?

Adding a tooltip to an image

I'm trying to add a tooltip to an image. Following a PyGTK tutorial it seems that this should work:
image = gtk.Image()
image.set_from_file(image_path)
box.pack_start(image, expand=False)
tooltip = gtk.Tooltips()
tooltip.set_tip(image, "Hello!")
Except it doesn't. Nothing happens when I mouse over the image. However, I know that works with buttons (I ran the sample code from the tutorial).
With GTK 2.12 and above, I could probably just use image.set_tooltip_text("Hello!") but I'm stuck at 2.10.4 and have to use gtk.Tooltips.
Edit
According to the documentation for gtk.Tooltips:
Tooltips can only be set on widgets which have their own X window. To check if a widget has its own window use widget.flags()&gtk.NO_WINDOW. To add a tooltip to a widget that doesn't have its own window, place the widget inside a gtk.EventBox and add a tooltip to the eventbox instead.
So that solves my problem but leaves me a bit confused. I checked the flags for a button and it has the same gtk.NO_WINDOW flag that images have. So why don't buttons need an EventBox but images do?
To satisfy its interface, GktButton creates an event box (well, something like an event box) for itself, internally. I.e. it captures events in a non-visible gdk window. GtkImage doesn't have a similar interface to satisfy so it doesn't need to capture events.
Perhaps it's an accident of the button's internal implementation that using the tooltip interface works without embedding a button in an EventBox or perhaps the tooltip interface actually depends upon a gdk window whether it's visible or not and the Widget interface lacks that sort of flag.

wxFrame not closing

I have a frame which I use as the main form (mainFrame), it inherits from mainFrameBase, which inherits from wxFrame.
It has a "close" system button. When it is pressed the app shuts down. All very much to my liking.
I inherit another frame from mainFrameBase (progScreen). When a button is pressed, the progScreen is shown. When I click its system close button, the form does not close.
What I want to achieve with this setup is that you can click a button on the main frame and a slightly different view of the main frame is shown to allow the user to "progam" certain buttons.
By the way, I'm using WXFormBuilder (excellent program) to create the screens.
What I would do is create two panels with the controls you want, one for the regular screen and one for the programming screen. Then when you want to switch, you hide one panel and show the other. That way, both screens are contained in one frame that when closed, exits the program. I actually have a tutorial that is similar to this here:
http://www.blog.pythonlibrary.org/2010/06/16/wxpython-how-to-switch-between-panels/
Hope that helps!

Categories