I just installed Python3 (3.5.2) and Pyqt5 (5.8.2) and I am following this tutorial to learn and make a GUI: http://zetcode.com/gui/pyqt5/firstprograms/
I'm trying to run the 2nd example but program is returning an error (which also happened on the 1st one, but since it had no image i took no notice) which is the following:
QApplication: invalid style override passed, ignoring it.
No XVisualInfo for format QSurfaceFormat(version 2.0, options QFlags<QSurfaceFormat::FormatOption>(), depthBufferSize -1, redBufferSize 1, greenBufferSize 1, blueBufferSize 1, alphaBufferSize -1, stencilBufferSize -1, samples -1, swapBehavior QSurfaceFormat::SwapBehavior(SingleBuffer), swapInterval 1, profile QSurfaceFormat::OpenGLContextProfile(NoProfile))
Falling back to using screens root_visual.
What is the meaning of this? Am i missing some packages?
I installed pyqt first with this command:
sudo -H pip3 install PyQt5
but Python3 was not acknowledging its existence so i searched the apt ubuntu repos and installed with:
sudo apt install python3-PyQt5
I also tried to reference the image by full path /foo/bar/image.png and nothing
What is the problem?
EDIT #1
The code that i am using is from example 2:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
"""
ZetCode PyQt5 tutorial
This example shows an icon
in the titlebar of the window.
author: Jan Bodnar
website: zetcode.com
last edited: January 2015
"""
import sys
import os
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
base_dir = os.path.dirname(os.path.abspath(__file__))
os.chdir(base_dir)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('image.png'))
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
After your post i reinstalled all my packages. The error is slightly different but the result is the same:
python3 example_02.py
QApplication: invalid style override passed, ignoring it.
Screencapture:
Notice that you are having no icons at all for all applications, not just for the PyQt icon example. This is because by default, certain environments turn off the icons in the titlebar. You have to enable them.
For instance in Xfce Desktop Environment, we can use the xfce4-settings-editor tool. In Settings/Settings Editor select xfwm4.
Find the show_app_icon option and check it. Change a theme back and forth to see the changes; they are not visible right away.
After this, you will see the icon in the titlebar of the PyQt5 example.
As for the warning; it is a recent thing and it has to do something
with the incopatibilities between Qt and GTK theming. I have not found
a solution to remove the warning so far.
So first off, you have no errors in your code. That's more akin to a warning but not even. What the following line is telling you
QApplication: invalid style override passed, ignoring it
is that your style option is invalid. If that were an error your script wouldn't run at all.
What I see right off the bat is this, you never supply a path to your image.
Now if the image is in the same root directory as the script then it should recognize said image without a path. But if you're attempting to do what I think you are it wouldn't work like that anyway. I think you're trying to create a launcher icon as well as a title bar icon, which typically goes hand in hand.
It appears to me that you've added it to Atom as some form of resource file. In which case most Ide's create a path for that file. Sometimes it's a path, other times a local url. QT its self does both when working with the QT creator.
I've never used Atom so I can't tell you how that works.
What I can say is this. you're using Linux which means .ico files are useless. I told you before linux doesn't handle icon files the same way windows does. This is most likely your problem.
So I sugesst you take a look at this
https://askubuntu.com/questions/476981/how-do-i-make-a-desktop-icon-to-launch-a-program
After you read that take a look at this if you have to https://help.ubuntu.com/community/UnityLaunchersAndDesktopFiles#Using_a_text_editor
Both of those links explain how to create a launcher icon for your program.
The following link will explain how to set the icon on the menu bar (title bar) in your program.
PyQt4 set windows taskbar icon
I hope this helps you out!
I study PyQt5 from author who give this question,also I have this problem that my icons can't show,I try some ways to catch it,that's what I do,hope it works!
First, it's important that you should use absolute path of the icons,for example:
self.setWindowIcon(QIcon("F:/Workspace/PyQT5-Study/images/web.png"))
but this not a good idea,so you can use second way like this:
from PyQt5.QtCore import QFileInfo
# ...
def initUI(self):
# ...
root = QFileInfo(__file__).absolutePath()
self.setWindowIcon(QIcon(root+'/images/web.png'))
# or
# import os
# current_dir = os.path.dirname(os.path.realpath(__file__))
# self.setWindowIcon(QIcon(os.path.join(current_dir, 'images/web.png')))
# ...
Last, if your icons also can't show, you should check this icon, if it's a legal icon.
In short, the normal images are unlimited so more, they can store many images and transform easily, but the icons have sure size,color kind,and more important,the icons have transparency, that means you can see the background, they have frame(not always straight). So you can use the web online tools to transform your image and try again,that really help me!
Also you should check the icon's source format, ensure you never change it, like .jpg to .png,and other. This will produce problem!
Wish you can solve the problem!
On windows be sure to use a real .ico file and a full path
iconpath = os.path.join(os.getcwd(),'qtlearning','assets','python.ico')
self.setWindowIcon(QIcon(iconpath))
I faced the exact same problem.
First things first. There is no setWindowIcon() method under QWidget or QMainWindow classes, in fact. you should be trying to set the QIcon at the Application level as follows.
app = QApplication(sys.argv)
app.setWindowIcon(QtGui.QIcon('home.png'))
Second, the icon thus created using this code does not reflect on the title of the window, instead it will reflect as an application icon as shown in the image below. the home.png
" icon for Application" in Ubuntu and not the " icon over the Window Title"
Finally, the path does not really matter, it can be an absolute path or a relative path, the system will consider either.
i just provided the full path of icon as simple as that
Related
I'm trying to use QFileDialog to get a list of the paths of selected folders AND directories.
I know how to do one or the other using QFileDialog.getOpenFileNames and QFileDialog.getExistingDirectory, but not both at the same time.
The C++ docs and other questions elsewhere didn't seem to help me no matter how much I googled.
I am using PyQt5 5.14.2 and Python 3.8.2 on Windows.
Edit:
I've managed to conjure up the following solution not using the native Windows dialog and it works but seems 'hacky'. Can anyone think of a better solution?
from PyQt5 import QtWidgets
main_window = QtWidgets.QApplication([])
dlg = QtWidgets.QFileDialog()
dlg.setFileMode(QtWidgets.QFileDialog.Directory)
dlg.setOption(QtWidgets.QFileDialog.DontUseNativeDialog, True)
_list = dlg.findChild(QtWidgets.QListView, 'listView')
if _list:
_list.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
tree = dlg.findChild(QtWidgets.QTreeView, 'treeView')
if tree:
tree.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
selected = None
if dlg.exec():
selected = dlg.selectedFiles()
print(selected)
There is a bug opened several years ago asking for this feature. Feel free to vote for it to get the attention of Qt developers
I have an application with two main windows. I want both of then to have the standard title which contains the file name and application name. But this works strange because both files show the file name but only the second window shows the application name. The first shows just "x.py" while the second "y.py - My App". Anybody has an idea why is that and how to solve it? Is this a bug or is it expected behaviour?
from qtpy.QtWidgets import QApplication, QMainWindow
app = QApplication([])
app.setApplicationDisplayName("My App")
wnd1 = QMainWindow()
wnd2 = QMainWindow()
wnd1.setWindowFilePath("x.py") # in most cases it shows only "x.py" - this is wrong
wnd2.setWindowFilePath("y.py") # correctly shows "y.py - My App"
wnd1.show()
wnd2.show()
app.exec_()
Tested on Ubuntu 16.04., PyQt 5.8.2.
UPDATE: So I also discovered it behaves non-deterministically. Sometimes both application titles appear correctly. Sometimes only one. This seems like a bug.
As a workaround for this likely bug I am going to override the setWindowFilePath() for my main window classes. This will give me another benefit such as showing the full file path instead of just file name and also indicate that the file is unnamed if it is a new file which has not yet been saved or loaded, which is what I want anyway. It also works well with changing window-modified state. I know I am sacrificing the 100 % 'native' look but... I can live with it.
def setWindowFilePath(self, filePath):
super(MainWindow, self).setWindowFilePath(filePath)
if not filePath:
filePath = "unnamed"
self.setWindowTitle("{}[*] - {}".format(filePath, qApp.applicationDisplayName()))
Maybe somebody will find a better solution.
The common regular python file dialog from Tk crashes under Enthought Canopy.
What is the recommended way to get a file dialog for Canopy users?
The code below works fine for regular python:
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
Error msg when run under Canopy is:
2014-12-30 11:22:52.809 Python[51980:d0f] -[QNSApplication _setup:]: unrecognized selector sent to instance 0x108657b70
Depends on what GUI backend you are using in your program. If your program also uses TK elsewhere, then follow the instructions in the link that Warren provided. If all you need is this dialog (and similar), Chuck's suggestion is probably easiest (especially since Qt is the default backend for IPython kernel that Canopy uses). I'm no Qt guru but I think you can simplify Chuck's suggestion to:
from PySide import QtGui
fname, _ = QtGui.QFileDialog.getOpenFileName(None, 'Choose file','.')
See http://srinikom.github.io/pyside-docs/PySide/QtGui/QFileDialog.html
For me, the easy alternative is to use Qt.
fname, _ = QtGui.QFileDialog.getOpenFileName(self.view, 'Open file','.')
I'm using a custom QFileDialog because I want to select multiple directories.
But the exec_ function is very slow, and I can't figure out why. I'm using the newest version of PyQt.
Code Snippet:
from PyQt4 import QtGui, QtCore, QtNetwork, uic
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
uic.loadUi('gui.ui', self)
self.connect(self.multiPackerAddDirsBtn,
QtCore.SIGNAL('clicked()'), self.multiPackerAddDirs)
def multiPackerAddDirs(self):
dialog = QtGui.QFileDialog(self)
dialog.setFileMode(QtGui.QFileDialog.Directory)
dialog.setOption(QtGui.QFileDialog.ShowDirsOnly, True)
dialogTreeView = dialog.findChild(QtGui.QTreeView)
dialogTreeView.setSelectionMode(
QtGui.QAbstractItemView.ExtendedSelection)
if dialog.exec_():
for dirname in dialog.selectedFiles():
self.multiPackerDirList.addItem(str(dirname))
print(str(dirname))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec_()
The QFileDialog constructor creates a Qt dialog, whereas the static functions (like getSaveFileName) will create a native one (unless the DontUseNativeDialog option is set to True).
The native dialogs may be faster or slower than Qt's, depending on the platform in use.
For some plaforms, though, it appears the problem may be more acute. See this longstanding bug, which affects Windows XP and Windows 7 (amongst others) with Qt 4.7 / 4.8.
UPDATE
Just to be clear:
On Windows, the static function QFileDialog.getExistingDirectory opens the native "Browse For Folder" dialog, which only allows selecting a single directory. So Qt cannot provide a native dialog for selecting multiple directories, because Windows doesn't provide one.
The other main alternative is to use Qt's own, non-native file-dialog and monkey-patch it as suggested in this faq. However, as you've already discovered, this currently has the significant downside of being annoyingly slow due to bugs in the underlying implementation.
The only remaining alternatives are to either write your own directory-lister dialog, or try to think of another way of solving your immediate problem (i.e. without using a file-dialog).
I had very very slow performance from the default Qt file browser dialog. Listing a directory took ~5s and selecting a file took ~3s. Adding the "DontUseNativeDialog" option fixed my problem completely.
file_path = QtGui.QFileDialog.getSaveFileName( self, 'Title', path, "", "", QtGui.QFileDialog.DontUseNativeDialog )
print file_path
I am writing a program using Tkinter that is to be eventually compiled into an exe using py2exe. I want to include an icon with it for use on the windows. It will be the same one as I have packed as the icon for the exe. Is there a way to include the icon in Tkinter, either by locating the exe file or using a file-like object? I know that win32api can find the current exe file that's running, but I believe that py2exe extracts the original file to temp, and then runs it, so the original exe couldn't be found that way. I also thought of putting it in an include folder, but I don't know if the cwd would be set correctly for that. Thanks for the help in advance!
Tk images have a -data option which lets you embed the image within the code. You just have to base64-encode the image. I think the image has to originally be in the GIF format.
Here's a working example:
import Tkinter as tk
root = tk.Tk()
data = '''R0lGODlhIAAgALMAAAAAAAAAgHCAkC6LV76+vvXeswD/ANzc3DLNMubm+v/6zS9P
T6Ai8P8A/////////yH5BAEAAAkALAAAAAAgACAAAAS00MlJq7046803AF3ofAYY
fh8GIEvpoUZcmtOKAO5rLMva0rYVKqX5IEq3XDAZo1GGiOhw5rtJc09cVGo7orYw
YtYo3d4+DBxJWuSCAQ30+vNTGcxnOIARj3eTYhJDQ3woDGl7foNiKBV7aYeEkHEi
gnKFkk4ciYaImJqbkZ+PjZUjaJOElKanqJyRrJyZgSKkokOsNYa2q7mcirC5I5Fo
fsK6hcHHgsSgx4a9yzXK0rrV19gRADs=
'''
img = tk.PhotoImage(data=data)
label = tk.Label(image=img)
label.pack()
root.mainloop()
You can embedd the icon in the py2exe binary with the icon_resources option
setup(windows=[
{'script':'toto.py', "icon_resources": [(1, "toto.ico")]},
],
Then you can retrieve it with the windows api
import win32gui, win32api, win32con
from ctypes import c_int, windll
hicon = win32gui.CreateIconFromResource(win32api.LoadResource(None, win32con.RT_ICON, 13), True)
and then attach to a window as long as you know his HWND.
windll.user32.SendMessageA(c_int(hwnd), c_int(win32con.WM_SETICON), c_int(win32con.ICON_SMALL), c_int(hicon))
The 13 constant used in the LoadResource has been retrieved with a tool like ResourceHacker. In ResourceHacker, it corresponds to the folder name of the icon. I don't know how it is calculated by py2exe and if there is a way to force this value.
I don't know also if there is a pure TkInter way to do that and if the icon can be used as-is in a tkinter window.
I hope it helps