Re: [PyKDE] Systray icons in PyQt
Roberto Alsina schrieb: Hello, 2nd version of ctypes code and Python extension module with one func only. The spec can be found here http://freedesktop.org/Standards/systemtray-spec/systemtray-spec-0.1.html, the code itself is taken from qjackctl (qjackctl.sf.net). When the code has undergone some review, I'll put it into the wiki. Should it be distributed somewhere else? Maybe it could go into the PyQt examples directory? Honestly? I´d put it up as part of PyQt itself. It´s just too handy. Of course The PyQt way would be a sip wrapper instead of this ;-) If you want to have a sip "wrapper", you'll need a C++ class first, which then has to be distributed with PyQt or by itself. Or it could be done as another way of implementing QLabel (another name, some more functions), but I do not know if it is possible to modify the constructor in PyQt. greetings Torsten -- Torsten Marek <[EMAIL PROTECTED]> ID: A244C858 -- FP: 1902 0002 5DFC 856B F146 894C 7CC5 451E A244 C858 www.keyserver.net -- wwwkeys.eu.pgp.net signature.asc Description: PGP signature signature.asc Description: OpenPGP digital signature
Re: [PyKDE] Systray icons in PyQt
Phil Thompson schrieb: On Thursday 27 May 2004 4:22 pm, you wrote: Hello, 2nd version of ctypes code and Python extension module with one func only. The spec can be found here http://freedesktop.org/Standards/systemtray-spec/systemtray-spec-0.1.html, the code itself is taken from qjackctl (qjackctl.sf.net). When the code has undergone some review, I'll put it into the wiki. Should it be distributed somewhere else? Maybe it could go into the PyQt examples directory? Fine by me. I guess what's really needed is a cross-platform QSysTray class. Of course you are right - but I gave away my harddisk with my win2k installation, thus, I cannot be of any help regarding cross-platformness. And is there such a concept on OS X? Regarding windows, as far as I remember, it is impossible to embed widgets into the TNA in Windows, just icons by ShellNotifyIcon{A,W}(...), that makes event handling a bit more difficult. But I might be proven wrong. greetings Torsten -- Torsten Marek <[EMAIL PROTECTED]> ID: A244C858 -- FP: 1902 0002 5DFC 856B F146 894C 7CC5 451E A244 C858 www.keyserver.net -- wwwkeys.eu.pgp.net signature.asc Description: PGP signature signature.asc Description: OpenPGP digital signature
Re: [PyKDE] Systray icons in PyQt
Hello, 2nd version of ctypes code and Python extension module with one func only. The spec can be found here http://freedesktop.org/Standards/systemtray-spec/systemtray-spec-0.1.html, the code itself is taken from qjackctl (qjackctl.sf.net). When the code has undergone some review, I'll put it into the wiki. Should it be distributed somewhere else? Maybe it could go into the PyQt examples directory? greetings Torsten -- Torsten Marek <[EMAIL PROTECTED]> ID: A244C858 -- FP: 1902 0002 5DFC 856B F146 894C 7CC5 451E A244 C858 www.keyserver.net -- wwwkeys.eu.pgp.net import qt import ctypes as c class SystrayIcon(qt.QLabel): """On construction, you have to supply a QPixmap instance holding the application icon. The pixmap should not be bigger than 32x32, preferably 22x22. Currently, no check is made. The class can emits two signals: Leftclick on icon: activated() Rightclick on icon: contextMenuRequested(const QPoint&) """ def __init__(self, icon, parent = None, name = ""): qt.QLabel.__init__(self, parent, name, qt.Qt.WMouseNoMask | qt.Qt.WRepaintNoErase | qt.Qt.WType_TopLevel | qt.Qt.WStyle_Customize | qt.Qt.WStyle_NoBorder | qt.Qt.WStyle_StaysOnTop) self.setMinimumSize(22, 22); self.setBackgroundMode(qt.Qt.X11ParentRelative) self.setBackgroundOrigin(qt.QWidget.WindowOrigin) libX11 = c.cdll.LoadLibrary("/usr/X11R6/lib/libX11.so") # get all functions, set arguments + return types XDefaultScreenOfDisplay = libX11.XDefaultScreenOfDisplay XDefaultScreenOfDisplay.argtypes = [c.c_void_p] XDefaultScreenOfDisplay.restype = c.c_void_p XScreenNumberOfScreen = libX11.XScreenNumberOfScreen XScreenNumberOfScreen.argtypes = [c.c_void_p] XInternAtom = libX11.XInternAtom XInternAtom.argtypes = [c.c_void_p, c.c_char_p, c.c_int] XGrabServer = libX11.XGrabServer XGrabServer.argtypes = [c.c_void_p] XGetSelectionOwner = libX11.XGetSelectionOwner XGetSelectionOwner.argtypes = [c.c_void_p, c.c_int] XSelectInput = libX11.XSelectInput XSelectInput.argtypes = [c.c_void_p, c.c_int, c.c_long] XUngrabServer = libX11.XUngrabServer XUngrabServer.argtypes = [c.c_void_p] XFlush = libX11.XFlush XFlush.argtypes = [c.c_void_p] class data(c.Union): _fields_ = [("b", c.c_char * 20), ("s", c.c_short * 10), ("l", c.c_long * 5)] class XClientMessageEvent(c.Structure): _fields_ = [("type", c.c_int), ("serial", c.c_ulong), ("send_event", c.c_int), ("display", c.c_void_p), ("window", c.c_int), ("message_type", c.c_int), ("format", c.c_int), ("data", data)] XSendEvent = libX11.XSendEvent XSendEvent.argtypes = [c.c_void_p, c.c_int, c.c_int, c.c_long, c.c_void_p] XSync = libX11.XSync XSync.argtypes = [c.c_void_p, c.c_int] dpy = int(qt.qt_xdisplay()) trayWin = self.winId(); iscreen = XScreenNumberOfScreen(XDefaultScreenOfDisplay(dpy)) # get systray window (holds _NET_SYSTEM_TRAY_S atom) selectionAtom = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S%i" % iscreen, 0) XGrabServer(dpy) managerWin = XGetSelectionOwner(dpy, selectionAtom) if managerWin != 0: # set StructureNotifyMask (1L << 17) XSelectInput(dpy, managerWin, 1L << 17) XUngrabServer(dpy); XFlush(dpy); if managerWin != 0: # send "SYSTEM_TRAY_OPCODE_REQUEST_DOCK to managerWin k = data() k.l = (0, # CurrentTime 0, # REQUEST_DOCK trayWin, # window ID 0, # empty 0) # empty ev = XClientMessageEvent(33, #type: ClientMessage 0, # serial 0, # send_event dpy, # display managerWin, # systray manager XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", 0), # message type 32, # format k) # message data XSendEvent(dpy, managerWin, 0, 0, c.addressof(ev)) XSync(dpy, 0) self.setPixmap(icon) self.setAlignment(qt.Qt.AlignHCenter) if parent: qt.QToolTip.add(self, parent.caption()) def setTooltipText(self, text): qt.QToolTip.add(self, text) def mousePressEvent(self, e): if e.button() == qt.Qt.RightButton: self.emit(qt.PYSIGNAL("
Re: [PyKDE] Systray icons in PyQt
On Thu, 27 May 2004 00:26:11, Hans-Peter Jansen <[EMAIL PROTECTED]> wrote: > On Wednesday 26 May 2004 03:52, Torsten Marek wrote: > > (sorry, but I'm too lazy right know to find out all the links). All > > you need to do is to call some functions in libX11.so. For that, > > you need the Display > > (qt_x11_display()) and the WindowID (QWidget.winId()) > > First of all: well done, Thorsten. It's really impressive to see how it was achieved. I didn't realise that the ctypes module made this sort of thing so straightforward. It appears to work just as well as the KSystemTray class, too. > > So far, there are several ways to do the C calls from Python: > > - extension module > > - Pyrex I don't think Pyrex really works all that well with C++, but maybe I didn't try hard enough to get them working together. David ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Systray icons in PyQt
On Thursday 27 May 2004 00:26, Hans-Peter Jansen wrote: > > First of all: well done, Thorsten. Grmpf, failed to spell your name... Sorry, Torsten. Pete ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
Re: [PyKDE] Systray icons in PyQt
On Wednesday 26 May 2004 03:52, Torsten Marek wrote: > > (sorry, but I'm too lazy right know to find out all the links). All > you need to do is to call some functions in libX11.so. For that, > you need the Display > (qt_x11_display()) and the WindowID (QWidget.winId()) First of all: well done, Thorsten. > So far, there are several ways to do the C calls from Python: > - extension module > - Pyrex > - ctypes > > I chose the ctypes way and after some hassle (mostly typos!), I got I would prefer a sip module. Since I tried to get it going, I also have some valid reason.. It wasn't that easy to build ctypes self contained (with the libffi snapshot statically linked) I'm just uploading a rpm to [EMAIL PROTECTED] for others with SuSE 9.0 to try: http://sf.net/project/showfiles.php?group_id=61057&package_id=57413&release_id=241234 > it to actually work. It's not very advanced by now. To try it out, > just replace the icon filename with something icon on your system. > I put in all values in good faith and they are poorly documented > right now, but I'll fix that later on. More comments and some docs would be really great. > I'll go to bed now Me, too. Cheers, Pete ___ PyKDE mailing list[EMAIL PROTECTED] http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
[PyKDE] Systray icons in PyQt
Hello all, for a project of mine, I need a systray icon. I know that it is possible to get a one with PyKDE and there is a solution for PyGtk, but not for PyQt itself. But the code is rather easy and I found out that the ppl of qjackcontrol implemented a systray icon in Qt for themselves, using the spec + sample code from freedesktop.org (sorry, but I'm too lazy right know to find out all the links). All you need to do is to call some functions in libX11.so. For that, you need the Display (qt_x11_display()) and the WindowID (QWidget.winId()) So far, there are several ways to do the C calls from Python: - extension module - Pyrex - ctypes I chose the ctypes way and after some hassle (mostly typos!), I got it to actually work. It's not very advanced by now. To try it out, just replace the icon filename with something icon on your system. I put in all values in good faith and they are poorly documented right now, but I'll fix that later on. I'll go to bed now greetings Torsten -- Torsten Marek <[EMAIL PROTECTED]> ID: A244C858 -- FP: 1902 0002 5DFC 856B F146 894C 7CC5 451E A244 C858 www.keyserver.net -- wwwkeys.eu.pgp.net import sys import qt from ctypes import * class SystrayIcon(qt.QLabel): def __init__(self, parent = None, name = ""): qt.QLabel.__init__(self, parent, name, qt.Qt.WMouseNoMask | qt.Qt.WRepaintNoErase | qt.Qt.WType_TopLevel | qt.Qt.WStyle_Customize | qt.Qt.WStyle_NoBorder | qt.Qt.WStyle_StaysOnTop) self.setMinimumSize(22, 22); self.setBackgroundMode(qt.Qt.X11ParentRelative) self.setBackgroundOrigin(qt.QWidget.WindowOrigin) libX11 = cdll.LoadLibrary("/usr/X11R6/lib/libX11.so") # get all functions, set arguments + return types XDefaultScreenOfDisplay = libX11.XDefaultScreenOfDisplay XDefaultScreenOfDisplay.argtypes = [c_void_p] XDefaultScreenOfDisplay.restype = c_void_p XScreenNumberOfScreen = libX11.XScreenNumberOfScreen XScreenNumberOfScreen.argtypes = [c_void_p] XInternAtom = libX11.XInternAtom XInternAtom.argtypes = [c_void_p, c_char_p, c_int] XGrabServer = libX11.XGrabServer XGrabServer.argtypes = [c_void_p] XGetSelectionOwner = libX11.XGetSelectionOwner XGetSelectionOwner.argtypes = [c_void_p, c_int] XSelectInput = libX11.XSelectInput XSelectInput.argtypes = [c_void_p, c_int, c_long] XUngrabServer = libX11.XUngrabServer XUngrabServer.argtypes = [c_void_p] XFlush = libX11.XFlush XFlush.argtypes = [c_void_p] # XClientMessageEvent class data(Union): _fields_ = [("b", c_char * 20), ("s", c_short * 10), ("l", c_long * 5)] class XClientMessageEvent(Structure): _fields_ = [("type", c_int), ("serial", c_ulong), ("send_event", c_int), ("display", c_void_p), ("window", c_int), ("message_type", c_int), ("format", c_int), ("data", data)] # XEvent struct class XEvent(Union): _fields_ = [("xclient", XClientMessageEvent)] XSendEvent = libX11.XSendEvent XSendEvent.argtypes = [c_void_p, c_int, c_int, c_long, c_void_p] XSync = libX11.XSync XSync.argtypes = [c_void_p, c_int] dpy = int(qt.qt_xdisplay()) trayWin = self.winId(); print "mywinid: 0x%x" % trayWin screen = XDefaultScreenOfDisplay(dpy) iscreen = XScreenNumberOfScreen(screen) selectionAtom = XInternAtom(dpy, "_NET_SYSTEM_TRAY_S%i" % iscreen, 0) XGrabServer(dpy) managerWin = XGetSelectionOwner(dpy, selectionAtom) print "managerWin: 0x%x" % managerWin if managerWin != 0: XSelectInput(dpy, managerWin, 1L << 17) XUngrabServer(dpy); XFlush(dpy); print managerWin if managerWin != 0: k = data() k.l = (0, 0, trayWin, 0, 0) ev = XClientMessageEvent(33, #type 0, # serial 0, # send_event dpy, # display managerWin, # window XInternAtom(dpy, "_NET_SYSTEM_TRAY_OPCODE", 0), # message type 32, # format k) XSendEvent(dpy, managerWin, 0, 0, addressof(ev)) XSync(dpy, 0) img = qt.QImage("/usr/share/rattlesnake/pixmaps/rattlesnake64.png") pm = qt.QPixmap() pm.convertFromImage(img.smoothScale(22, 22), 0) self.setPixmap(pm)