PyQt graphicsview resize event - events

I would like to connect a resize event on a graphics view to a function using PyQt. I added the QGraphicsView to the GUI using QtCreator. I have tried a few variations without success:
gv.pyqtConfigure(resize=self.printR)
QtCore.QObject.connect(gv,QtCore.SIGNAL("resized()"),self.printR)
gv.resize.connect(self.printR)
However none of the above work (I have tried using many variations of the event name).
What is the correct way of doing this?
As an expanded question, is there a definitive list anywhere of all the signals available to different widgets in Qt, i.e. all the possible values that could be passed to SIGNAL(), or the "signal" attributes available to a widget (e.g. button.clicked.connect())?

The PyQt class reference is the best place to look for signals and class methods.
Connecting simple signals can be done like this:
self.connect(senderObject, QtCore.SIGNAL("signalName()"), self.slotMethod)
As far as I can tell, however, most widgets do not normally emit a signal when they are resized. In order to do this, you would need to re-implement the QGraphicsView class and its resizeEvent method, modifying it to emit such a signal, like so:
from PyQt4.QtGui import QGraphicsView
from PyQt4.QtCore import SIGNAL
class customGraphicsView(QGraphicsView):
def __init__(self, parent=None):
QGraphicsView.__init__(self, parent)
def resizeEvent(self, evt=None):
self.emit(SIGNAL("resize()"))
Using Qt Designer, you should be able to turn your existing QGraphicsView widget into a placeholder for such a custom widget by right-clicking on it and selecting Promote to.... For help, look here.
I hope this sufficiently answers your question.

Related

Window control receives mouse-wheel events but not scroll-bar events

I have a dialog-box (derived from CDialog).
Inside it, I have a window control (CWnd) in which I display a bitmap image.
I would like this window control to be scrollable, so I create it as follows:
m_Window = CreateEx(0,
WC_STATIC,
NULL,
WS_CHILD|WS_VSCROLL|WS_HSCROLL|SS_BITMAP,
{0,0,width,height},
this,
0);
Now, it receives mouse-wheel events, but it doesn't receive scroll-bar events (in other words, it reaches the OnMouseWheel handler, but it doesn't reach the OnVScroll and OnHScroll handlers).
What exactly am I missing here?
I tried adding an SS_NOTIFY flag to the window style when creating it, but no luck with that.
I also tried calling EnableScrollBar(SB_BOTH,ESB_ENABLE_BOTH), but no luck with that either.
One thought I have in mind, is that the WC_STATIC class type is simply not designated for that.
I tried looking for a more suitable class type by jumping to the definition of WC_STATIC in file CommCtrl.h and searching for other class types (putting #define WC_ in the search-box).
But there are too many of them, and I'm not even sure it's the right direction.
Anyone familiar with this problem?
Thank you.

Fast way to obtain underlying java component for controls in matlab

I'd like to obtain a reference to underlying java components for the controls I have in my GUI so as to customize their appearance.
I know about findjobj from Yair Altman which works really well:
myLink = uicontrol('String', '<html><u>Button that looks like a link.</u></html>');
jObj = findjobj(myLink);
jObj.setContentAreaFilled(0);
Unfortunately this solution is quite slow when there are a "lot" of controls to customize (because it has to parse the full hierarchy of objects in the figure and this for each control to customize).
Moreover the figure must be visible (else controls are not instantiated and java references cannot be found). Plus it must be moved of screen to avoid users to touch it while findjobj is running (sometimes make things crash because findjobj somehow relies on position of controls to find them while internally calling also drawnow which updates positions) ...
On some machines, even with only a few controls to customize, it can be up to 10 seconds before to have the figure to appear (most of the time is spent in findjobj).
I also know about uicomponent again from Yair Altman to directly create controls and get the handle to the underlying java component in one shot:
[myLink, jObj] = uicomponent('Style', 'JButton', 'String', '<html><u>Button that looks like a link.</u></html>');
jObj.setContentAreaFilled(0);
Unfortunately here the parent property can only be a figure and of course my controls are placed in gui layout containers to handle resizing and many other things nicely (and gui layout containter are not valid hg-handles for uicomponent to work)...
So was wondering if there could be any other fast solution to get underlying java components for controls in my GUI ? ... NB: I mainly only need to have buttons that looks like hyperlinks or animated gif (i.e. borderless buttons with htlm text/img inside).
This isn't a direct answer to your question, but I've built several GUIs that are based around GUI Layout Toolbox and that contain Java swing components. I typically arrange things so that the GUI Layout container (HBox, VBox, Grid etc) has a uipanel as a child, and then the uipanel has the Java swing component as a child.
You can typically parent a Java component to the uipanel in exactly the same way as parenting it to a figure (unlike a GUI Layout container), and it's no problem to parent a uipanel to a GUI Layout container.
So, for example, to add a button with a dropdown menu (no menu items, so it won't do anything, but just to illustrate):
>> u = uipanel;
>> ddbuttonclass = 'com.mathworks.widgets.DropdownButton';
>> ddbutton = javaObjectEDT(ddbuttonclass);
>> [jddbutton, hjddbutton] = javacomponent(ddbutton, [30,30, 60, 30], u);
Now you can parent u to a GUI Layout container, and you get all the nice resizing.
I'm not that familiar with Yair's uicomponent, but if you can get the handle of the java component somehow, you should be able to use something like the above.
PS If you want his direct input, #Yair is sometimes active on SO - he may get notified if I mention his name. If you're doing a lot of Java/MATLAB GUI work, I'd also recommend buying his book.
UICOMPONENT was designed to be a direct replacement of both Matlab's built-in UICONTROL and JAVACOMPONENT functions. This means that you can directly place a UICOMPONENT within panels, even those created by the GUI Layout toolbox.
You might need to cast the layout panel's handle to double (double(hPanel)) on some Matlab releases but that's about it:
[myLink, jObj] = uicomponent('Parent',hPanel, ...);
[myLink, jObj] = uicomponent('Parent',double(hPanel), ...); % on some Matlab releases
You could also use JAVACOMPONENT directly, but it doesn't really give you any benefits over UICOMPONENT, since UICOMPONENT uses JAVACOMPONENT under the hood and also adds important functionality (such as ensuring the component is placed on the EDT, and merging important properties from the Matlab wrapper).
As for FINDJOBJ, you can speed it up a bit by specifying the target object class using the 'class' parameter. But if your figure contains hundreds of controls it might still be slow. To this day, close to 10 years after my first version of FINDJOBJ, I still do not know of a direct way to get the underlying Java object. I assume there is one that is used internally by MathWorks, but I do not know it.
As #SamRoberts mentioned, this is all discussed in my book...

What is the equivalent of python's "window.get_property("visible") in GTK+ (C)?

In order to show some window upon a clicking a button in the main window, i have to use "on_delete_event" signal to show or hide the appropriate windows. I know the pygtk "window.get_property("visible")". I searched the documentation there is no such thing as gtk.get
_property all i found was "gtk.mnemonics.get_visible or something like this.
I'm pretty sure somebody has used show and hide stuff in GTK+(C)
The functions you want are g_object_get() and g_object_set(). These apply to all GObjects, not just GtkWidget.
In the case of GtkWidget's "visible" property there is also a gtk_widget_get_visible() function (and a gtk_widget_is_viisble() function that also checks all parents of a GtkWidget) and an equivalent gtk_widget_set_visible().
Remember that GtkWindow is derived from GtkWidget; the former will use the latter's methods and properties where appropriate.

Building a gui app using wxPython

Am building a gui app using wxpython,i have created two separate windows in two different files,i.e app1.py and app2.py,I want to open the 2nd window(app2.py) using a button click on first window(app1.py). How do i achieve this. It would be great if someone can help,Thanks!!
I am assuming you're using wxPython's definition of "window" (i.e. anything that is actually viewable in the GUI), not the regular definition of "separate box with stuff in it and an X button in the corner" (which wxPython calls a "frame")
When I was writing my first wxPython GUI I was faced with a similar probem. I wanted actions in one panel to affect the data shown in another. My first solution was to write methods that blindly passed the request to the panel's parent until it reached the top level (my "main frame", if you will). This worked, but obviously it's a terrible solution.
My second solution was to use wxPython Events, just like catching button presses for a wx.Panel. My idea was I would create a button in one frame and bind wx.EVT_BUTTON with that button's ID in another. I made custom Events and CommandEvents. While trying to implement this solution I discovered that do not propogate and that CommandEvents will only propogate through the parents. So, if left uncaught a CommandEvent will eventually hit your "main frame" but it will never hit the second panel unless that panel happens to be a parent of where the Event came from. Obviously, this won't work for you since the parent can't be hidden but a child be visible. Plus it would leave your main frame cluttered with code and methods to delegate commands.
Finally, I found the answer! wx.lib.pubsub! Basically, you bind the button press in app1.py, just like normal. Now, in the handler you use pubsub to publish a custom message. Next, in the init for app2.py, you use pubsub to subscribe to your custom message (I like having a "message.py" where I declare all my messages as constants). When you subscribe to a message you assign a handler method, just like for events.\
Read this: http://wiki.wxpython.org/WxLibPubSub
Since you said you wanted the window to APPEAR, maybe in the init method for app2.py you call the Hide() method then when you receive the message, call Show().
When I implemented this in my application I was using wxPython2.8. I am now using 2.9 so I don't know if this is still necessary but I found that I need the top import in order to call pubsub.subscribe() and pubsub.sendMessage(). I kept getting errors otherwise. I can't remember how I figured this out, I think I saw it in a code sample and added it in a desperate attempt to make my code work. I suggest you read the documentation I linked above and try to implement your code WITHOUT that import first.
import wx
from wx.lib.pubsub import setupkwargs #I need this to force pubsub to work. I don't know why.
from wx.lib.pubsub import pub
ID_MYBUTTON = wx.NewId()
class App1(wx.Panel):
def __init__(self, parent):
wx.Panel.__init___(self, parent)
button = wx.Button(self, ID_MYBUTTON, "Show App2")
self.Bind(wx.EVT_BUTTON, self.handleButton, id=ID_MYBUTTON
def handleButton(self, event):
pubsub.sendMessage("mybutton.pressed") #send the message
class App2(wx.Window):
def __init__(self, parent):
wx.Window.__init__(self, parent)
self.Hide() #I don't want to be seen yet
pubsub.subscribe(self.gotMessage, "mybutton.pressed") #listen for the message
def gotMessage(self):
self.Show() #Now I want to be seen!
-----EDIT-----
I found this SO question that might help: Creating child frames of main frame in wxPython
Please tell us in detail what you're trying to do? wxPython also has "dialogs" which would be better than a frame if all you're doing is showing the user a message or asking for a bit more information. http://wxpython.org/docs/api/wx.Dialog-class.html
It really depends on what you're trying to accomplish. We can't help you unless you explain what problem you're trying to solve.
-----EDIT AGIAN-----
It's looking like the person asking the question did indeed want a wx.Dialog. For a tutorial, see http://zetcode.com/wxpython/dialogs/ Also see Python WX - Returning user input from wx Dialog

Help with qt4 qgraphicsview

I've done lots of stuff with pygtk however i'm deciding to learn pyqt, im stuck at the qgraphicsview i have absolutley no idea how to get signals from the items i place on the graphics view, primarily mouse events.How do i get the mouse events from idividual items in a scene?
QGraphicsItem is not a QObject and cannot send signals, nor receive slots. Instead, you must handle events. You can do that either through an event filter, sub-classing the view or scene to intercept events or simply sub-classing the items themselves and implementing the event handling functions (see protected member functions in the documentation). Perhaps this example can be of interest: http://doc.trolltech.com/4.6/graphicsview-diagramscene.html .
Right after you create an item, connect the signals you want from it to the instance of the widget that contains it.
Another option is to just give up using signals and have your instance of QGraphicItem directly call a method of its parent by keeping a reference to it. This is less pretty than using signals but ultimately, it gets the job done.

Resources