Windows Icons

Python und das Qt-Toolkit, erstellen von GUIs mittels des Qt-Designers.
Antworten
waki
User
Beiträge: 133
Registriert: Dienstag 9. März 2010, 16:41

Guten Tag,
ich bin gerade daran mit PyQt4 soetwas wie einen Explorer per QTreeWidget zu machen, jedoch bekomm ich es nicht hin, dass ich sagen kann, dass er immer die Icons wie bei Windows nehmen soll. Gibt es eine möglichkeit die Icons-Einstellungen von Windows zu übernehmen oder muss ich jeden Icon einzeln einbinden? Danke schonmal...

gruß

€: Wie kann per Signale erkennen welcher "Ordner" geöffnet wurde? Also wie heißt das Signal (z.B. clicked())? Und genause bräuchte ich das wenn der "Ordner" geschlossen wird.
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Mir ist kein Weg mit PyQt bekannt, elegant die systemweiten Icons von Windows zu erhalten. Mit einem Rückgriff auf die WinAPI kommst Du an die gewünschten Infos:

Code: Alles auswählen

from ctypes import Structure, c_long, c_char, windll, c_wchar_p, sizeof, byref
from ctypes.wintypes import HICON, DWORD, MAX_PATH
from PyQt4.QtGui import QPixmap

#typedef struct _SHFILEINFO {
#  HICON hIcon;
#  int   iIcon;
#  DWORD dwAttributes;
#  TCHAR szDisplayName[MAX_PATH]; --> 260
#  TCHAR szTypeName[80];
#} SHFILEINFO;
class SHFILEINFO(Structure):
    _fields_ = [('hIcon', HICON),
                ('iIcon', c_long),
                ('dwAttributes', DWORD),
                ('szDisplayName', c_char*MAX_PATH),
                ('szTypeName', c_char*80)] 

#DWORD_PTR SHGetFileInfo(
#  __in     LPCTSTR pszPath,
#           DWORD dwFileAttributes,
#  __inout  SHFILEINFO *psfi,
#           UINT cbFileInfo,
#           UINT uFlags  --> SHGFI_ICON (0x000000100)
#);
SHGetFileInfo = windll.shell32.SHGetFileInfoW

#BOOL WINAPI DestroyIcon(
#  __in  HICON hIcon
#);
DestroyIcon = windll.user32.DestroyIcon

def pixmap_from_path(path):
    '''Return a QPixmap of system icon for path (unicode).'''
    fileinfo = SHFILEINFO()
    SHGetFileInfo(c_wchar_p(path), 0, byref(fileinfo), sizeof(fileinfo), 0x100)

    # Leider taucht die Funktion fromWinHICON(ptr) nicht in der PyQt-Doku auf.
    # Sie erwartet ein sip.voidptr-Objekt, welches den Python <long> Typen nicht
    # versteht und HICON (=c_ulong) in ein "signed" <int> ueberfuehrt werden muss.
    # Ohne cast verweigert die Funktion den Dienst fuer Adressen >= 2^31.
    pix = QtGui.QPixmap.fromWinHICON(c_long(fileinfo.hIcon).value)
    DestroyIcon(fileinfo.hIcon)
    return pix
Tipp: Bau Dir ein dictionary mit den Dateiendungen, für die Du das Icon kennst, dann musst Du die Funktion nur für neue Typen aufrufen:

Code: Alles auswählen

filetype_pixmaps.setdefault('txt', pixmap_from_path(u'bla.txt'))
@Signale:
Die Items des TreeWidgets liefern verschiedene Signale aus, z.B. 'itemClicked'. Siehe Doku.

Vllt. sind QTreeView und QDirModel einen Blick wert. Die Model/Viewklassen erlauben eine bessere Trennung von Programmlogik und Repräsentation und sollten daher den item-basierten Widgetklassen vorgezogen werden.

Edit:
Hab gerade gesehen, dass die Modelklassen fürs Dateisystem (QFileSystemModel) die nativen Icons inzwischen verwenden. :oops: Damit entfällt das händische Auslesen der Icons.
Zuletzt geändert von jerch am Montag 15. November 2010, 14:38, insgesamt 1-mal geändert.
lunar

Das passende Symbol für eine Datei oder ein Verzeichnis erhält man mittels "QFileIconProvider". Für andere native Symbole muss man unter Windows allerdings trotzdem die Windows-API bemühen. Unter Linux dagegen reicht "QIcon.fromTheme()".

Sinnvollerweise aber implementiert man eine „Explorer“-ähnliche Ansicht auf Basis von "QFileSystemModel", dann muss man die Symbole auch nicht selbst laden.
waki
User
Beiträge: 133
Registriert: Dienstag 9. März 2010, 16:41

ok, hab mir gerade mal QFileSystemModel angesehen, und so wie ich das verstanden habe, kann ich damit nur Daten auf meiner Festplatte damit managen. Jedoch bekomme ich bei meinem Programm die Daten von einem anderen Pc. Diese sind über das Internet verbunden und ich baue jetzt einen Explorer mit dem ich das Dateisystem des anderen Pcs durchsuchen kann.

€: Gibt es eine Möglichkeit statische Informationen zum Pfad des Icons oder so, also dass ich für txt immer nur einen bestimmten pfad laden muss, ohne eine datei scannen zu lassen?
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

hat eigentlich irgendwer ein projekt in arbeit, native bzw. nativ aussehende* icons unter den windowsen per Icon.fromTheme() bereitzustellen? so könnte man eine cross-plattform-anwendung deployen, bei der man sich nicht drum kümmern muss, dass windows bzgl. icons eigentlich extrawürste braucht.

*in windows sind ja viele icons nicht enthalten, da windows (7) selbst wenige programme enthält, die direkt mit der bearbeitung von dateien zu tun haben. mir fällt jetzt nur note- und wordpad, sowie paint ein.
lunar

@flying sheep: Um das umzusetzen, müsste man erst einmal eine Abbildung finden von Freedesktop-Symbolen auf Windows-Symbole. Vollständig ist das ohnehin nicht umzusetzen, da die Freedesktop-Symbolsammlung wesentlich mehr verschiedene Symbole umfasst als Windows selbst, und der Rest ist vor allem Fleißarbeit, die sich eben noch niemand machen wollte.

Es ist unter Windows daher einfacher, ein gut aussehendes Symbolthema mitzuliefern.
flying sheep
User
Beiträge: 48
Registriert: Donnerstag 17. September 2009, 16:44
Kontaktdaten:

schon klar. jemand, der ein gut passendes theme mitliefert, müsste dann ein projekt starten à la „hier schon mal ein paar icons, verwendet die, wenn ihr zusätzliche braucht und macht, ladet sie hier hoch“. wär vllt. interessant, mal nach projekten ausschau zu halten, die einige icons enthalten…
waki
User
Beiträge: 133
Registriert: Dienstag 9. März 2010, 16:41

Ich hätte nochmal eine Frage dazu:
Wenn ich zum Beispiel weiß, wo ein bestimmter Icon unter Windows liegt, z.B. "C:\WINDOWS\SYSTEM\shell32.dll,40". Wie kann ich diesen dann als Icon in PyQt4 laden?
Antworten