How to change the function called when I click in the close button on php-gtk? - php-gtk

I load a single instance of a window on php-gtk, I have a button named "Cancel" that hide(); the window, so when the window is needed again I just show();.
But when I click on the close button instead of the cancel button the window is destroyed. Even when I redirect the event (I'm not sure if i'm doing it right) it calls the first(just hide() function) and then the destroy method.
Any idea?
PD: I wouldn't want to destroy and recreate the windows because of php's crappy garbage collector and to be able to maintain previous data without having to refill the whole window(after all is supposed to be a desktop app).

Following the advice here: delete-event.
I changed my code to return TRUE:
function on_multipleCancelButton_activate()
{
global $GladeMultiple;
$MultipleWindow = $GladeMultiple->get_widget('multipleWindow');
$MultipleWindow->hide();
return TRUE;
}
On the GTK designer I linked the delete-event to this function.

Related

How to get the hand/controller that pressed a button

I would like to know, just by subscribing to the Interactable OnClick event, if I pressed the button with my left or right hand. Would that even be possible without passing this information along with the OnClick event?
The button has quite the logic to go through until it decides to accept a click request, so replicating all of that via global listener is not feasible.
Is it possible to get that information OnClick from somewhere else? Is it possible to query the potential click sources for who that was?
Without altering the Interactable class the only way I found was to query the FocusProvider for the active pointer, which must have been the one pressing the button (in my case):
https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/Input/Pointers.html
https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/Input/Controllers.html
Setup your controllers, take note of the axis name, in code you can do something like this in any GameObject's update loop:
if (Input.GetAxis("Axis1D.PrimaryHandButton") > 0.5f) {
// this axis (button) is pressed do something
}

What happens with MFC dialog form after OK button click

What happens with MFC dialog form when I click OK button. Looks like it is not destroyed since it's constructor was not executed. I have pointer to this form StatusDlg * statusDlg;. How to know this form is not visible? How to use this form once again and show to user?
How to destroy this form completely?
I create it like:
statusDlg = new StatusDlg(NULL);
statusDlg->Create(StatusDlg::IDD,CWnd::GetDesktopWindow());
statusDlg->ShowWindow(SW_SHOW);
And when it is created I press OK.
I don't know what you mean by "it's constructor was not executed"... I assume you meant to say that it's destructor was not executed.
That would be true.
Eventually, what happens is that the API function EndDialog(m_hWwnd, IDOK) gets called on your dialog. That causes your dialog to be hidden.
However, the window handle of the dialog and it's pointer is still valid. On program termination, the window will be destroyed but your C++ destructor will still never be called. If you want to ensure your destructor is called, overried PostNcDestroy() like this:
void StatusDlg::PostNcDestroy()
{
__super::PostNcDestroy();// might be able to be skipped if baseclass does nothing, which I suspect is the case
delete this; // deletes this StatusDlg
}
Your statusDlg pointer can tell you whether the window is visible. Just call statusDlg->IsWindowVisible()--assuming you hang onto the statusDlg pointer somewhere.
If you override PostNcDestroy() like I did, then you NEVER want to make a call like:
delete statusDlg; // bad things will happen... (attempted double deletion)
Instead, you want to do this:
statusDlg->DestroyWindow(); // PostNcDestroy() takes care of deletion
What I said above holds true for modeless dialogs. For modal dialogs, it is done slightly different.

Getting pyqt application focus for popup menu to disappear when clicking away from it

Let me quickly explain the background to this. I'm developing a custom menu system inside a 3D application called Softimage XSI. It has a PyQt application object created already and ProcessEvents is being called a certain number of times every second so that PyQt applications can exist in a non-modal state within XSI.
To implement the menu, I've got a webpage embedded in a toolbar which is calling a plugin for XSI that I've written to show a PyQt menu. This all works fine (albeit, slightly contrived!).
The issue is that when I show the menu, it won't disappear when I click away from it. If I move the mouse over the menu, and then click away from it, it will disappear. It's only when it first pops up.
I've tried everything I can think of. Here's a list:
Using QtGui.qApp.installEventFilter(menu) to try and catch the mousepressed signal. It never gets triggered. I suspect the application itself isn't receiving the click.
Using menu.raise_() makes no difference
Neither does QtGui.qApp.setActiveWindow(menu)
Or menu.setFocus()
I've also tried:
event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, pos, QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier)
QtGui.qApp.sendEvent(menu, event)
I had a go writing my own QEventLoop, but it just crashed XSI. I suspect trying to run a modal loop inside the other one probably isn't a legal thing to do. Either that, or I really don't know what I'm doing (equally probable)
The only thing I have partial success with is using grabMouse(). This is what makes the menu close if I click away from the menu (only after the mouse has passed over the menu once), but I have to call it a couple of times for it to "stick".
So this is my code at the moment:
class MyMenu (QtGui.QMenu):
def __init__(self, parent = None):
QtGui.QMenu.__init__(self, parent)
self.grabbed=2
def getMouse(self):
if self.grabbed>0:
self.grabMouse()
self.grabbed-=1
def paintEvent(self, event):
QtGui.QMenu.paintEvent(self, event)
self.getMouse()
def hideEvent(self, event):
self.releaseMouse()
def ShowMenu():
menu = MyMenu()
menu.addAction("A")
menu.addAction("B")
menu.addAction("C")
submenu = MyMenu()
submenu.addAction("D")
submenu.addAction("E")
submenu.addAction("F")
menu.addMenu(submenu)
menu.setTearOffEnabled(True)
menu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setStyleSheet("font: 8pt \"Sans Serif\";")
submenu.setTitle("Window")
submenu.setTearOffEnabled(True)
pos = QtGui.QCursor.pos()
pos.setX(105)
menu.popup(pos)
#Prevent garbage collection
QtGui.XSIMenu=menu
QtGui.XSISubMenu=submenu
#Desperate acts!
menu.raise_()
QtGui.qApp.setActiveWindow(menu)
menu.setFocus()
Any thoughts or random suggestions would be very gratefully received as this is driving me nuts! Don't be afraid to suggest modifications to stuff I've already tried, as I'm relatively new to PyQt and I may well have missed something.
Many thanks,
Andy
Just before calling popup with self.trayMenu.popup(QtGui.QCursor.pos()), call self.trayMenu.activateWindow(). Putting activateWindow before popup makes the left-click menu work the same as the right-click menu and it goes away when you click elsewhere. :)

How to save the window state at wxWidgets?

I'm constructing a UI using wxWidgets.
In my GUI, I generate a window (wxFrame class) which is accessible through pushing a bitmap button. In that window, I also perform some tasks, again pushing some bitmap buttons and diabling them etc. But I can't close and reopen that window with the state saved. I always have to re-initialize it, and this is very impractical.
How can I save the state of my window? I checked the internet, it's suggested to use wxPersistent class but this class is missing in my wxWidgets.
Thank you for any help,
Best Regards.
Instead of destroying the window every time, you can just hide it with the wxWindow::Show() member function, passing false as the argument, when you receive a wxCloseEvent. You then veto the wxCloseEvent to prevent WxWidgets from destroying your window:
// In your close handler:
if(evt.CanVeto()) // Where evt is a wxCloseEvent
{
Show(false); // Hide window
evt.Veto(); // Prevent window destruction
}
This should remove it from the screen, but all the initialized parts should still be there. If you need to show it again, call the Show() method again with true.

How do I disable Qt's behavior on Linux of capturing arrow keys for widget focus navigation

I'm working on a Qt app that is developed primarily on MacOS, but that is then built and tested on Linux as well.
We define a keyPressEvent() method in our main window class to respond to certain keyboard events. Among others, we respond to Qt::Key_Left, Qt::Key_Right and Qt::Key_Space. This works great on MacOS. On Linux, however, we never get these events.
Doing some Googling (and confirming it with our app's behavior on Linux), it seems that the reason for this is that Qt uses these keys for keyboard navigation of button widgets in the application's GUI. If I press the arrow keys on Linux, I cycle through all the active button widgets, selecting each on in turn. If I click the spacebar, the currently selected button is pressed.
All I've been able to find so far by Googling is suggestions as to how to either subclass or apply filters to specific buttons to avoid this behavior by having the button ignore the event and pass it along. But I don'w want to have to do this for every button widget I ever put into my GUI. That's just lame.
Is there a way to disable this behavior globally and allow my app code to actually get ALL of the arrow key and spacebar events?
You can set add global event listener to catch these events.
In the window constructor:
QApplication::instance()->installEventFilter(this);
In the window's eventFilter method:
bool MainWindow::eventFilter(QObject *object, QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
qDebug() << "key" << key_event->key() << "object" << object;
//...
}
return false;
}
If you have processed an event, you should return true from this function. You can use object variable to find out the source of event. For example, it can be some QPushButton. You can check if this button is a child of your main window if it's necessary (if you have multiple top windows).
Another way is to disable focus for buttons completely. Set buttons' focusPolicy to NoFocus. Then they will not catch key events.
Also you can subclass QPushButton and reimplement keyPressEvent with empty implementation.

Resources