How do I tell if a QIcon lacks a valid pixmap? - qt

If I create a QIcon with a pixmap as in the following code snippet:
from PyQt5 import QtGui
icon = QtGui.QIcon(':/images/view-refresh.png')
How do I tell if the icon doesn't have a valid pixmap, e.g. because ':/images/view-refresh.png' wasn't found?

My solution is to wrap the QIcon constructor in a factory function that creates an explicit QPixmap, which is probed to see if it is valid:
def create_icon(filename):
pixmap = QtGui.QPixmap(filename)
if pixmap.isNull():
raise ValueError('No icon with filename \'{}\' found'.format(filename))
return QtGui.QIcon(pixmap)
icon = create_icon(':/images/view-refresh.png')
Note that there is also a QIcon.isNull method, but according to the documentation it can be false even if the pixmap is invalid.

The documentation for Icon.isNull() specifically says it returns false only if it has neither a pixmap nor a filename.
Looking through the list of member functions, availableSizes() looks like a better candidate. Ive tested this.
So good test to see if an icon is valid is len(icon.availableSizes())>0.

Related

How to use QStyle::standardIcon/standardPixmap with QStyle::StandardPixmap?

In my code there is a bunch of calls which try to create QIcons from
QStyle standard pixmaps, like:
QIcon groupIcon;
groupIcon.addPixmap( style()->standardPixmap( QStyle::SP_DirClosedIcon ),
QIcon::Normal, QIcon::Off );
groupIcon.addPixmap( style()->standardPixmap( QStyle::SP_DirOpenIcon ),
QIcon::Normal, QIcon::On );
While this works correctly, in that using the icon for a model's
Qt::DecorationRole shows either an open or closed icon based on the item's
expanded state, it has two issues:
It's not hi-dpi friendly, and the icons are tiny
QStyle::standardPixmap is marked as obsolete, with QStyle::standardIcon being described as the preferred approach.
I'm unsure how to translate the above code to QStyle::standardIcon though.
QIcon groupIcon( style()->standardIcon( QStyle::SP_DirClosedIcon ) );
works nicely for closed items, and looks great on hidpi. But I can't see how I would add the SP_DirOpenIcon state. There's no equivalent method like "QIcon::addIcon" like there is QIcon::addPixmap.
What's the correct approach to take here, which is hi-dpi friendly and future proof?
how to translate the above code to QStyle::standardIcon
To be able to use QStyle::standardIcon instead of QStyle::standardPixmap, select the particular pixmap from the icon with QIcon::pixmap.
Here is an example I have prepared for you of how to change your code in order to accomplish that:
QIcon groupIcon;
QSize sz(16, 16);
groupIcon.addPixmap(style()->standardIcon(QStyle::SP_DirClosedIcon).pixmap(sz),
QIcon::Normal, QIcon::Off);
groupIcon.addPixmap(style()->standardIcon(QStyle::SP_DirOpenIcon).pixmap(sz),
QIcon::Normal, QIcon::On);
Here 16 is the requested size. Please note, that:
The pixmap might be smaller than requested, but never larger.
hence adjust this value accordingly.

Qt Set image to label reference variable

I have some pictures in the resource file and their file names correspond to their staffIds. this is how I set the picture into my QLabel but nothing is shown.
QString staffId;
staffId=ui->lineEdit_staffID->text();
QPixmap managerPic(":/staff/\'"+staffId+"\'.jpg");
managerInterface.ui->label_mpic->setScaledContents(true);
managerInterface.ui->label_mpic->setPixmap(managerPic);
I'm with #Mike here, most probably the single quotes aren't part of your filenames. You can use the debugger to see what is passed to the QPixmap constructor, or put the name into a separate QString variable and write it to qDebug() to see what it contains.
In general you better use QString::arg() to build strings instead of concatenation; usually it's easier to read and understand:
QPixmap managerPic(QString(":/staff/\'%1\'.jpg").arg(staffId));
QPixmap managerPic(QString(":/staff/%1.jpg").arg(staffId));

looking for example for QCompleter with segmented completion / tree models

The PySide docs include this section on QCompleter with tree models:
PySide.QtGui.QCompleter can look for completions in tree models, assuming that any item (or sub-item or sub-sub-item) can be unambiguously represented as a string by specifying the path to the item. The completion is then performed one level at a time.
Let’s take the example of a user typing in a file system path. The model is a (hierarchical) PySide.QtGui.QFileSystemModel . The completion occurs for every element in the path. For example, if the current text is C:\Wind , PySide.QtGui.QCompleter might suggest Windows to complete the current path element. Similarly, if the current text is C:\Windows\Sy , PySide.QtGui.QCompleter might suggest System .
For this kind of completion to work, PySide.QtGui.QCompleter needs to be able to split the path into a list of strings that are matched at each level. For C:\Windows\Sy , it needs to be split as “C:”, “Windows” and “Sy”. The default implementation of PySide.QtGui.QCompleter.splitPath() , splits the PySide.QtGui.QCompleter.completionPrefix() using QDir.separator() if the model is a PySide.QtGui.QFileSystemModel .
To provide completions, PySide.QtGui.QCompleter needs to know the path from an index. This is provided by PySide.QtGui.QCompleter.pathFromIndex() . The default implementation of PySide.QtGui.QCompleter.pathFromIndex() , returns the data for the edit role for list models and the absolute file path if the mode is a PySide.QtGui.QFileSystemModel.
But I can't seem to find an example showing how to do this. Can anyone point me at an example I can use as a starting point? (In my investigation it looks like maybe the hard part is the tree model rather than the QCompleter)
It looks like you would need to provide these functions:
ability to split a string into segments (for the example given, C:\Windows\Sy to ['C:','Windows','Sy']
the ability to specify the list of items that include the last segment (e.g. all the items included in ['C:','Windows']
I found an example for the basic functionality of QCompleter and have been able to tweak the basics fine (see below), I just don't know how to go about implementing a tree model type application.
'''based on
http://codeprogress.com/python/libraries/pyqt/showPyQTExample.php?index=403&key=QCompleterQLineEdit'''
from PySide.QtGui import *
from PySide.QtCore import *
import sys
def main():
app = QApplication(sys.argv)
edit = QLineEdit()
strList = '''
Germany;Russia;France;
french fries;frizzy hair;fennel;fuzzball
frayed;fickle;Frobozz;fear;framing;frames
Franco-American;Frames;fancy;fire;frozen yogurt
football;fnord;foul;fowl;foo;bar;baz;quux
family;Fozzie Bear;flinch;fizzy;famous;fellow
friend;fog;foil;far;flower;flour;Florida
'''.replace('\n',';').split(";")
strList.sort(key=lambda s: s.lower())
completer = QCompleter(strList,edit)
completer.setCaseSensitivity(Qt.CaseInsensitive)
edit.setWindowTitle("PySide QLineEdit Auto Complete")
edit.setCompleter(completer)
edit.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
I couldn't find a good example for what I wanted, but I figured out how to adapt the Qt TreeModel example to using a QCompleter:
https://gist.github.com/jason-s/9dcef741288b6509d362
The QCompleter is the easy part, you just have to tell it how to split a path into segments, and then how to get from a particular entry in the model back to a path:
class MyCompleter(QtGui.QCompleter):
def splitPath(self, path):
return path.split('/')
def pathFromIndex(self, index):
result = []
while index.isValid():
result = [self.model().data(index, QtCore.Qt.DisplayRole)] + result
index = index.parent()
r = '/'.join(result)
return r
Aside from that, you have to configure the QCompleter properly, telling it how to get from a model item to a text string. Here I set it up to use the DisplayRole and to use column 0.
edit = QtGui.QLineEdit()
completer = MyCompleter(edit)
completer.setModel(model)
completer.setCompletionColumn(0)
completer.setCompletionRole(QtCore.Qt.DisplayRole)
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
As the documentation for QCompleter says you can provide two models: a list model or a tree model.
Example for list model, after your example:
from PySide import QtGui
app = QtGui.QApplication([])
edit = QtGui.QLineEdit()
strList = "Germany;Russia;France;Norway".split(";")
completer = QtGui.QCompleter(strList)
edit.setCompleter(completer)
edit.show()
app.exec_()
works:
And as a tree model:
from PySide import QtGui, QtCore
app = QtGui.QApplication([])
edit = QtGui.QLineEdit()
model = QtGui.QFileSystemModel()
model.setFilter(QtCore.QDir.AllDirs | QtCore.QDir.Drives)
model.setRootPath('')
completer = QtGui.QCompleter(model, edit)
edit.setCompleter(completer)
edit.show()
app.exec_()
for some strange reason nothing is displayed here. Will investigate later.

how change textcolor editor in qt

this is my syntax editor program i want to show keyword,classes,function and ...with Separate color i set the color in config file(with Qsetting)
for example this in my config file :
FunctionColor=blue
an in my cod i read the the configfile:
QString FunctionColor=settings.value("FunctionColor").toString();
how i can set the color in this instruction:
functionFormat.setForeground(Qt::FunctionColor);
compiler gives error? what i must be doing????
It would be great if you provide clear snippet codes instead of the example instructions above. However, based on my guess, if you check Qt documentation,
setForeground
is taking QBrush type of parameter. That means, to get what you want probably, you need to add some logic to convert between the string value to the QBrush value, for example:
if (FunctionColor == "blue")
{
functionFormat.setForeground(Qt::blue);
}
See if this could fix the problem.

Flex - How does nativeApplication.icon work?

NativeApplication.nativeApplication.icon.bitmaps = bitmapData();
I'm trying to edit the bitmaps for the system tray icon, but I got an error:
Implicit coercion of a value of type flash.display:BitmapData to an unrelated type Array.
What mistake did I make, or could you tell me the meaning of this error?
Icon.bitmaps is an Array of BitmapData, with one BitmapData instance for each size. You must reassign the entire array:
NativeApplication.nativeApplication.icon.bitmaps = new Array(bitmapData);
Alternatively, as the livedocs mention, you can specify all the bitmap sizes:
NativeApplication.nativeApplication.icon.bitmaps =
new Array(icon16x16.bitmapData, icon128x128.bitmapData);
I think you need a typecast in there such as:
SystemTrayIcon(NativeApplication.nativeApplication.icon).bitmaps
The SystemTrayIcon is a Windows-specific class I believe.
This is the discussion about this topic from Adobe:
http://livedocs.adobe.com/flex/3/html/help.html?content=taskbar_1.html

Resources