Python / Gtk - embedding into X window ID - python

I wrote a program using Qt 4.8, which used the QX11Embed mechanism to embed a useful little python/gtk widget.
I forked the widget, got its winID and then embedded it in a Qt container widget. This worked well
Then I had to change to Qt5 and the whole QX11Embed code has been dropped:(
Apps that take a winID as a commandline arg and embed into it, like mplayer or xterm, still work with Qt5. You just create a container, pass its winID to the app, but not the other way around.
I am not a python programmmer, but even so I am considering changing the widget itself so that it embeds itself into a given winID, but I cannot find any examples or docs.
Every search that mentions embedding goes to the plug/socket mechanism for embedding INTO gtk, nothing the other way around.
How should I go about it, is it even possible, any links etc
Thanks

Related

Python PyQt6 (6.4.0) QML Difficulty in Applying Style to Qt.QWidgets

I am in the research/education phase now, and am not seeing a lot of info on the web about applying a Qml-based style to QWidgets. This implies it's difficult or not possible. I doubt it's impossible, but I am curious what the options are for doing that?
Ideally, what I want to do is use the system (user-chosen) theme in my application. I'm on Linux, and it uses GTK and GNOME for themes. I want to support Linux in general (maybe one day, other platforms), so would like to make the app theme cross-distro.
I don't know if this is a tall order. But, is it extremely involved to make PyQt6 QWidgets styled from a QML style? Can widgets use the system theme?

pyqt embed in photoshop

This is complex to explain, I hope this will not end up being a vague question getting vague answers.
If this is not the right place to ask this, you may help me to find the proper one.
I have a plugin for Photoshop based on the Listener, so it captures any input from the user.
The plugin creates a python module (called here "ps") containing basically the hInstance and the hwnd of the photoshop window.
Then this plugin, using plain python commands in the plugin for the module like those
PyRun_SimpleString("import Photoshop");
PyRun_SimpleString("Photoshop.showTools()");
will load a special module (here called "Photoshop") that will initialize pyqt and using the QtWinMigrate and the ps module to get the hInstance like this: QMfcApp.pluginInstance(ps.GetPluginInstance()), will start pyqt in photoshop. Here an example code of the Photoshop module using the ps module:
from PyQt4.QtWinMigrate import QMfcApp
from PyQt4.QtGui import QPushButton
import ps #this is implemented in the photoshop plugin (based on the Listener plugin)
#create the plugin instance here
app=QMfcApp.pluginInstance(ps.GetPluginInstance())
def showTools():
box = QPushButton()
box.show()
app.exec_()
Again then, the sequence is like this:
When the plugin starts in photoshop "ps" module is created, then it will load the "Photoshop" module that will load and bind properly pyqt. In the "Photoshop" module I can load any python module, widgets are properly working and everything works really well inside Photoshop.
But now the problem is: using Wacom tablets in Photoshop loose stroke sensitivity, the driver works and everything else works but the pressure sensitivity.
Apparently QMfcApp.pluginInstance will install an event filter to drive the Qt event loop while photoshop still owns the event loop. ( http://doc.qt.digia.com/solutions/4/qtwinmigrate/qmfcapp.html )
and on the paper looks fine to me.. but I could not manage to solve this by myself and I tried, more or less carefully, different approaches:
the listener plugin is not the problem. If Listener plugin runs but python is not initialized sensitivity works fine.
python itself is not a problem. If the listener starts python without gui nor pyqt, then works fine.
as soon as I call pluginInstance which should create the QApplication the issue starts and pressure is lost from the tablet. Even with the small code I wrote before.
Someone may have put pyqt as a plugin somewhere else, since the only purpose of QMfcApp is apparently this one. There is something I can configure to make it work? Is a known issue?
I would rather keep the approach (instead of connecting to photoshop externally like with COM)
I am not able to post the entire code here but let me know if you need something.. I probably can show more.
Thanks a lot for your help

Creating a multi-screen application using Qt Designer

I'm using Qt Designer to create UI designs which I'm then converting into python code. Since I'm quite new to Qt I'd like to ask: is there a way I could implement a multi-screen application? I.e. having a next button clicked and getting a new set of options/widgets etc within the same window.
To be honest, I was developing using Kivy, and as slick as that is (especially with multiple screens) it depends on PyGame, which proves to be an enormous portability headache, so I had to switch to something else, and PyQt was the next feasible option (or so it seems).
It's called a QWizard. It is not called a multi screen application, but if you search for wizard instead, you find lots of information.
Links
Example with C++ code
[PyQt QWizard documentation] http://pyqt.sourceforge.net/Docs/PyQt4/qwizard.html

Key binding for window/app in python Gtk+ 3 without menu items, UI manager, etc

I'm trying to use GTK3 and Cairo from Python for a minimal plotting application where the on-screen display of Cairo's output is for user convenience.
The typical usage is that I run a command, a plot pops up on screen and is also written to file, and I want to be able to dismiss the window as quickly as possible, ideally just a "q" keypress but also the common Ctrl-W and Ctrl-Q in addition to the default Alt-F4 (does anyone really use that regularly?!?).
I also want as little UI clutter in the window as possible: ideally just the standard window surround, no menus, toolbars, etc.
So... how can I bind my "q", "Ctrl-Q", etc. keybindings to Gtk.main_quit without having to a) create a cluttersome drop-down menu bar and b) go though the heavyweight Gtk.UIManager focused on by the Python Gtk+ 3 documentation here: http://python-gtk-3-tutorial.readthedocs.org/en/latest/menus.html . I hope this is possible, and doesn't require a lot of code (at least not as much as to set up all the menus!), but I can't find an example anywhere online: maybe I'm just searching for the wrong terms, being a GTK newbie.
Unfortunately there doesn't seem to be any documentation on making such a minimal accelerator setup, and the code to configure accelerator keys seems to differ a great deal between GTK2 and 3... thanks for helping.
Connect a signal to your main frame Win.connect('key-press-event', self.on_key_function) and in on_key_function (self, widget, event) check the value of event.keyval. For ESC is 65307 if you like hardcoded. Also, for key combinations, event.state report shift, alt(meta), and so on: if Gdk.ModifierType.CONTROL_MASK & event.state:do_something if ctrl is pressed
You could have separate stataments for left-ctrl, right-alt; be sure not to try to capture predefined key combinations, thay may be consumed by window manager.
A IDE with a good introspection will help you a lot, just write Gdk (previously imported) and autocompletion will popup a lot of functions/clases, most of them with a self-explanatory name.
Don't use key-press-event and keyval, it won't work for users with non-Latin keyboard layouts. GTK+ does a great job internally to match keyvals to hardware keys, this functionality is exposed via accelerators (often shortened as accel in the API) and bindings.

Trying to learn PyQt with knowledge from Tkinter

Maybe I'm jumping into the deep end, but I'll give it a shot.
Here are some useful features of Tkinter:
The Tkinter Canvas widget is an object oriented drawing canvas. The elements of the drawing are essentially widgets themselves, as they can be moved, modified, and bound to events.
Tkinter uses bindings to trigger callbacks. The event is passed as a string. Custom events can be easily created with event_generate.
Tkinter has the after method, which waits for a specified amount of time without freezing the GUI.
Tkinter has predefined fonts like TkDefaultFont, and colors like systemButtonFace, which are dependant on the system.
My questions are:
What are the pyQt equivalents of these features (especially the bold ones)?
How can I "bind" elements of a widget (e.g. the label of a checkbutton only) to an event?
In Qt and PyQt events are called signals and you bind to them using slots (docs here). Generally speaking what you do define a slot with an # decorator.
class WindowImpl (QtGui.QMainWindow, Ui_TremorMain, Ui_Graphs):
def __init__ (self, buffer, parent = None, configuration = None):
# do some initialisation here (not GUI setup however)
#QtCore.pyqtSlot(int, name="on_confSelectorCombo_currentIndexChanged")
def confChanged (self, newConf):
# do some stuff here to handle the event
The above would be triggered on the currentIndexChanged event of an object called confSelectorCombo. The setup of the confSelectorCombo is done in the GUI builder or Qt Creator as Nokia has decided to call it. This really is what you want to use to get started. There's tutorials here on using Qt Creator. Obviously you'll want to go through the docs and see what signals are emitted by which widgets.
As for the font stuff all I know is what it says on the docs:
If you have not set a font for your application then the default font on your
machine will be used, and the default font can be different on different
machines. On Windows the default Windows font is used, on X11 the one in qtrc
can be used. If a default font can’t be found, then a font specified by Qt
will be used.
The QStyleSheet and QStyle act as proxies for changing the appearance of widgets (QStylesheet,QStyle).
As for making the application wait I found this
QTime dieTime = QTime::currentTime().addSecs(2);
while( QTime::currentTime() < dieTime ):
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
There is also QThread.sleep() (docs), depending on what kind of an effect you want. Probably also worth looking at the threading support over at Qt docs
Overall in finding information about how to do stuff in PyQt I have found it surprisingly useful to look at the Qt documentation and then just writing the stuff in Python. 9 times out of 10 this works. On another note, it's probably also worth looking into PySide which is another python Qt library. I've haven't used myself before as it has been in the works previously but I noticed that they had released a 1.0.6 version.
UPDATE
Just to reiterate Luke Woodward below, you can use QGraphicsScene and QGraphicsView to render stuff in an object oriented way. The QGraphicsScene doesn't actually render anything it just a scene graph, the QGraphicsView is then used to render the contents of the scene graph. For low level drawing there´s also QPainter - there's a basic drawing tutorial here. It's also worth looking at QGraphicsItem which is the base for all graphics items and
includes defining the item's geometry, collision detection, its painting
implementation and item interaction through its event handlers
docs here. The Context2D provides an HTML canvas (if I'm not mistaken through the use of WebKit). The canvas itself only has a changed slot, but any objects you place on the canvas will/can have more slots. There's a fairly complete looking tutorial on Context2D and Context2DCanvas here. For an explanation as to why so many different ways of rendering stuff, you'll have to ask someone else. My two cents is that is has something to do with the fact that Qt is supposed to work everywhere and Trolltech and later Nokia wanted to provide lots of choice. Luckily the docs are really good.

Categories