I'm very new to pyside, qt and python.
I managed to setup a project with a basic window and a push button which closes the app.
My problem is, that somehow vscode won't show all properties available, even though the code runs with them fine.
Note how a bunch of other properties are suggested, except for the signal clicked. If I hover over clicked, it tells me clicked: Any
Only during debugging, vscode tells me what clicked is:
Current setup:
OS: Linux
Virtualenv with pyside2 installed
Using ms-python.python and ms-python.vscode-pylance
ui/MainWindow.ui file and corresponding generated ui/MainWindow_ui.ui file with pyside2-uic
You can generate the stubs manually by running
pyside6-genpyi all
PySide2 have the same tools, it's not just for PySide6.
I use PDM to handle my project, with the last one I execute:
pdm run pyside6-genpyi all
And PyLance detect all my stubs:
If you got error with the Signal, it's because Qt/PySide do some magic tricks and convert Signal to SignalInstance. My solution is to cast SignalInstance to get to right hint.
from typing import cast
from PySide6.QtCore import Signal, SignalInstance
class ConnectionPanel(QtWidgets.QWidget):
connected = cast(SignalInstance, Signal())
disconnected = cast(SignalInstance, Signal())
Pylance tries to use stub files(which you can traverse with Go to definition) of PySide6 library to offer intellisense features. According to Qt docs clicked signal should be defined in QAbstractButton class but in type definitions (stubs) we can't see this signal definitions. If you look closely PyCharm gathers it from QAbstractButton class in your linked video but Pylance in Vs Code searches it in QPushButton.
This was a known issue in Pylance since PySide2 but according to the Pylance repo this may originate from Qt for Python's incorrect type definitions:
Libraries that have typing that's either incorrect or doesn't work well with PyLance. Best and maybe most known example I have is PySide2 (but see issues with other libraries in earlier posts): tons(!) of errors for correct, working code, which makes spotting real errors difficult. The same code in PyQt5 (which is basically a twin sibling to PySide2) doesn't raise any complaints from PyLance, so I'm assuming the problem is with PySide2's typing. While I'm aware that neither PySide2's typing nor PyLance's analysis results are necessarily incorrect, fact is that most of the reported errors should not be present, so for sake of simplicity I'll just call it incorrect.
The reason it can access at runtime is; it's created instance over shiboken QObject type I guess. I don't have any workarounds but it doesn't bother me because I prefer following official Qt documentation when looking for which signals available in a class definition.
EDIT: There was a resolved bug report on this which is the reason PyCharm able to handle auto-completion. Opening another on VS Code should help.
Since I had this exact same problem, I found this very informative comment on a PySide bug report: https://bugreports.qt.io/browse/PYSIDE-1603
Our stubs are auto-generated by introspection, signals are not included. At the moment, we need to discuss how we should support signals.
So, not a bug, just a missing feature.
Related
I am making my first GUI application with PyQt5 but it does not currently work with dark mode.
How do you enable dark mode in PyQt5?
I user PyQt5 v5.13.0 and freeze the app with PyInstaller on Mac, Linux and Windows.
If you need more information or some of the code, please tell me.
Workaround for macOS X.
Install PyQt5 5.12.2
pip3 install pyqt5==5.12.2
Compile your app
Add this into info.plist:
<key>NSRequiresAquaSystemAppearance</key>
<string>False</string>
There is no much difference between 5.12.2 and 5.13.0 but later doesn't support native dark mode on macOS.
On other platforms write separate style sheets and add trigger in settings or read system variable.
There is no way (Built-in), except for external implementations of Stylesheets, or implementing by yourself..
I highly recommend checking this reply for one of those.
It speaks about this stylesheet.
In this thread there are also ways of how to implement it.
I struggled with this problem myself (PyQt5 5.14) and have figured out how to make macOS' dark mode work with PyQt5. You have to call QApplication.setStyle('style name here').
For whatever reason, it seems that any color scheme changes lay inert until "activated" by setStyle(). (You can see this if you call QApplication.setPalette(palette) with a custom palette; some colors will change and others won't—until setStyle() is called, upon which all colors finally change.) I can only speculate that dark mode was detected on app start but not activated.
Why it is that color scheme changes don't apply until setStyle() is called, I have no idea. I'm guessing it's a bug in PyQt5.
There are two rules to make the setStyle() trick work:
You must call setStyle() after you've instantiated your QApplication. This is in addition to the setStyle() call before instantiating your QApplication, for a total of two setStyle()s.
setStyle() must be called with a string argument. Giving it a QStyle object does nothing.
So, to have your app sync color schemes with macOS' dark mode:
# Must run before QApplication is instantiated, otherwise certain widget styles will remain unset
PyQt5.QtWidgets.QApplication.setStyle('fusion')
app = YourQApplicationClassHere(sys.argv)
# Must run after QApplication is instantiated, to apply any latent color scheme changes
PyQt5.QtWidgets.QApplication.setStyle('fusion')
Final caveat: If you freeze your app with pyinstaller, not even the setStyle() trick will work.
You can add this two lines at the very start of your code, before importing PyQt5/PySide2:
import os
os.environ["QT_MAC_WANTS_LAYER"] = "1"
No need to install a specific qt version, nor set NSRequiresAquaSystemAppearance to false on Info.plist.
Tested on macOS Mojave, Catalina and Big Sur.
I'm trying to make a program using PyQt5 and pyqtgraph, however, I keep running into this error:
ImportError: cannot import name 'QGraphWidget'
I used QtDesigner to make a form and promoted a QGraphicsWidget. I know I did it correctly (I've done it at least 10 times to try and resolve the issue), but the error persists.
I'm using Windows 7, Anaconda, and PyCharm, but I tried running the code in other environments and still got the error.
In the documentation it implies that the promoted name can be anything, however, this seems to be untrue (at least at the moment).
Under “Promoted class name”, enter the class name you wish to use (“PlotWidget”, “GraphicsLayoutWidget”, etc).
After re-doing my QGraphicsWidget for the 6th time, I decided to name it one of the example names in the tutorial, which seems to have solved the problem.
In other words name your widget and promoted widget "PlotWidget", "ImageView", "GraphicsLayoutView", or "GraphicsView". (Please keep in mind I have only tested "PlotWidget".)
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
I use Python in combination with the gtk3 and the GTKGLExt fork from https://github.com/tdz/gtkglext so I can use the gobject introspection feature to use Gtk3 from python.
I created a Gtk.DrawingArea to draw my OpenGL stuff. Everything works fine as long as I have just one instance of this widget.
However, I use a Gtk Notebook to have multiple instances of this widget present in different pages of the notebook (one widget per page).
Sometimes (meaning in a non deterministic way) the program crashes with a segmentation fault. I ran a stacktrace using gdb and located the problem to be the call to "gtk_widget_end_gl" which is placed at the end of my drawing, realize and configure handler methods (of course there is a gtk_widget_begin_gl at the beginning of each of those as well).
Here is the relevant excerpt from the stacktrace:
0 0xb1170b58 in _gdk_x11_gl_context_impl_get_current () at gdkglcontext-x11.c:514
1 0xb116c094 in gdk_gl_context_get_current () at gdkglcontext.c:244
2 0xb116c0b4 in gdk_gl_context_release_current () at gdkglcontext.c:215
3 0xb4d04592 in gtk_widget_end_gl (widget=0xa175608, do_swap=0) at gtkglwidget.c:549
and below is a minimal example of my realize method where the problem occurs where "widget" is an instance of Gtk.DrawingArea:
def on_realize(self, widget, *user_data):
if not GtkGLExt.widget_begin_gl(widget):
return False
gl.glClearColor(BACKGROUND_COLOR[0],
BACKGROUND_COLOR[1],
BACKGROUND_COLOR[2],
BACKGROUND_COLOR[3])
GtkGLExt.widget_end_gl(widget, False)
Since I am pretty much clueless why this problem occurs sometimes (around every 5th time a new widget is created) I wonder if anyone ever has experienced the same or can reproduce the problem or help me to find a solution.
I need to say that I don't manually create an OpenGL context here since in the provided examples this never seemed necessary and I figured the widget would do this on it's own. The stacktrace implies that there seems to be a problem getting the context. Whats startles me is the fact that this only happens sometimes. So if someone could even hint me how to tackle this problem I would be very glad as I am not an experienced C programmer.
Following the example at http://article.gmane.org/gmane.comp.python.general/541418, I've succeeded in creating a callable class for balloon tooltips, but the greater complexities of that code elude me when it comes to customization. I browsed a bit of how it works through msdn, but being a novice at more windows-esque languagues like c and vb, etc. I was unable to make much sense of it.
So I ask ye snakely academics:
Things I'd like to be able to do with that code aside from the standard icon, title, text:
Perform actions based on clicking the tooltip
Modify the tooltip that pops up over the icon in the system tray after loading it (to reflect changing values)
Multiple lines? (Not sure if this can even be done, really)
More information on other things you could do in a windows 7 environment versus XP (which seems to be what this was written for).
Ideally I'd get some sort of return value or some semblance of an event when the tooltip is clicked so that I could run some code, but currently I'm importing that code as a module and calling at various times, so I'm not sure how to handle clicks outside of the popup code itself...
Information on handling these things with python seems quite scarce. Thanks in advance.
Perform actions based on clicking the tooltip
Whats the problem OnTaskbarNotify? Hock yourself in there.
Modify the tooltip that pops up over the icon in the system tray after loading it (to reflect changing values)
Probably not, I am not sure about the WinAPI here. I haven't seen it in the wild, so...
Multiple lines? (Not sure if this can even be done, really)
With most WinAPI, just insert a \n in the string.
More information on other things you could do in a windows 7 environment versus XP (which seems to be what this was written for).
LOTS... But that is a bit vague... It depends what your needs are. But for kol feturez you need to google on your own...
On Linux and Unix systems I use the notify-send OS already implemented system.
import os
os.system('notify-send "'+title+'" "'+message+'")
Maybe in Windows there is some API32 for this.
Check this https://gist.github.com/wontoncc/1808234