How to use Mac OS X NSEvents within wxPython application? - python

I am writing an application that has to react to system wide keypresses on Mac OS X.
So I found some key logger examples that should work and hit a wall, because all examples are based on NSSharedApplication() and PyObjC AppHelper.runEventLoop() while my application is written in wxPython.
Here I post a modification of the simplest example from https://github.com/ljos
that I thought it should work. But it does not.
from AppKit import *
import wx
class AppDelegate(NSObject):
def applicationDidFinishLaunching_(self, aNotification):
NSEvent.addGlobalMonitorForEventsMatchingMask_handler_(NSKeyDownMask, handler)
def handler(event):
print (u"%#", event)
app = wx.App()
delegate = AppDelegate.alloc().init()
NSApp().setDelegate_(delegate)
app.MainLoop()
It is obvious that the MainLoop() doesn't catch the delegated NSEvents.
After app = wx.App() the NSApp() is returned correctly. So why doesn't this work? How do I make it work?

As nobody answered I went searching around with different angle in view.
So I discovered that Quartz module can be used to get to keyboard and mouse events. No custom loop needed, therefore wx.App() and wx.App.MainLoop() aren't getting in the way.
I also found a nice package named pynput that does just that for me, thus sparing me plenty of time. Quartz is pretty complicated, a lot of scrambled names for functions and constants. But it does a good job.

Related

How to use GTK4 without using the `Application` class?

Note how this application implements a mainloop by the activate signal and .run() method call:
import gi
gi.require_version("Gtk", "4.0")
from gi.repository import Gtk
def on_activate(app):
win = Gtk.ApplicationWindow(application=app)
btn = Gtk.Button(label="Hello, World!")
btn.connect('clicked', lambda x: win.close())
win.set_child(btn)
win.present()
app = Gtk.Application(application_id='org.gtk.Example')
app.connect('activate', on_activate)
app.run(None)
Correct me: I think this activate signal is emitted as an event to synchronise the creation of GTK windows, widgets, etc, so that the GUI part does not race to happen before the application is ready. What else is the point?
Then, when the Window, widgets, etc are all drawn, the application gets stuck in a mainloop by .run(). This way the application doesn't exit immediately, but rather waits for user input.
What bothers me here is that I don't see the value of the Application class. Because of it, we got an event on signal activate to tell "oh the app is ready", but what is this app anyway? Why can't I just do .run() on Gtk.ApplicationWindow or even Gtk.Window?
In order to answer those questions above, I invented/discovered this question that, if answered, I think it will address my frustration:
Question: What is the GT4 approach in running GUI apps without using Application or ApplicationWindow classes?
Background
I come from a TKinter background. There, I could make an app simply by saying something like:
import tkinter
class MyApp(tkinter.Tk):
def __init__(self):
super().__init__()
self.title('some title')
if __name__ == '__main__':
myapp = MyApp()
myapp.mainloop()
It feels much simpler, without a spaghetti of creating two objects (like in GTK4) with signals emitting through them just to barely get a .run() mainloop.
But I have to use GTK4 for this project, and Tkinter is not an option. So I have to learn the suitable GTK4 for me.
According to the docs: "GtkApplication is a high-level API for writing applications.
It supports many aspects of writing a GTK application in a convenient fashion, without enforcing a one-size-fits-all model.
Currently, GtkApplication handles GTK initialization, application uniqueness, session management, provides some basic scriptability and desktop shell integration by exporting actions and menus and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of your application.
While GtkApplication works fine with plain GtkWindows, it is recommended to use it together with GtkApplicationWindow."
Source: https://docs.gtk.org/gtk4/class.Application.html
The clasic hello world from Gtk3 will not work on Gtk4
This works:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
But if you change "3.0" by "4.0" does not work and the reason is on the migration guide:
"GTK 4 removes the gtk_main_* family of APIs. The recommended replacement is GtkApplication"
https://docs.gtk.org/gtk4/migrating-3to4.html#stop-using-gtk_main-and-related-apis
Gtk have a different approach to Tk, you will need to be used to that.
And GTK4 is still new, you will found more examples about Gtk3 code, so, keep the migration guide at hand

what do jumping rockets mean when running a python script?

I am working on a simple flask app. When I run it from my shell using python2 controller.py it works, but 2 jumping rockets appear on the bottom of my screen (I am using Mac).
Does it mean anything? It is strange for me since I often use python, but have never seen
something like this.
This means that your Python interpreter has attempted to interact with the GUI.
You can do this from your own scripts quite easily. For instance, you can run the Hello, tkinter example from the upstream docs:
from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()
Without knowing which libraries your Flask app uses, it's hard to say why it might have triggered this behavior. That said, you might look through sys.modules.keys() to see which Python libraries have been imported -- any GUI library will let you know this has happened; you can then bisect your imports (putting the code that checks sys.modules at different locations in the import section of your script) to see where it's happening.

Proper way of building Gtk3 applications in Python

I have just started learning about creating GUI apps in Python. I decided to use Gtk version 3.
According to the (official?) tutorial on http://python-gtk-3-tutorial.readthedocs.org/ the proper way of building a hello world application is:
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
self.set_default_size(200, 100)
self.connect('destroy', Gtk.main_quit)
self.show_all()
MyWindow()
Gtk.main()
In other tutorial (http://www.micahcarrick.com/gtk3-python-hello-world.html) I found completly different aproach which is:
from gi.repository import Gtk, Gio
class HelloWorldApp(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self, application_id="apps.test.helloworld",
flags=Gio.ApplicationFlags.FLAGS_NONE)
self.connect("activate", self.on_activate)
def on_activate(self, data=None):
window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
window.set_title("Gtk3 Python Example")
window.set_border_width(24)
label = Gtk.Label("Hello World!")
window.add(label)
window.show_all()
self.add_window(window)
if __name__ == "__main__":
app = HelloWorldApp()
app.run(None)
Could someone experienced in this category tell me in what way should I write Gtk 3 apps in python these days? I'm already familiar with writing GUIs (spent few months in Java's Swing) so you can go on with terms like events, callbacks and so on..
Choosing to write your new program with a GtkApplication or just a GtkWindow depends on the functionality you require, and to some extent the intended audience.
For most cases, especially when you are still learning the toolkit, I would tend to agree with valmynd that GtkApplication is unnecessarily complicated. GtkApplication provides a lot of extra functionality that you probably don't want or need in smaller applications.
For larger, more complete applications I agree with Dragnucs, the second approach is superior and can provide better integration into the desktop environment. From GNOME Goal: Port to GtkApplication (see also the GtkApplication docs):
Porting your application to use GtkApplication has quite nice benefits:
GtkApplication handles GTK+ initialization, application uniqueness, session management, provides some basic scriptability and desktop shell integration by exporting actions and menus and manages a list of toplevel windows whose life-cycle is automatically tied to the life-cycle of your application.
However I disagree with Dragnucs about why the GtkWindow approach is introduced in the tutorial. I tend to think simple examples with very little boilerplate are more appropriate for a tutorials Getting Started section (but, I do think that the read-the-docs tutorial needs to be updated to include at least some mention of GtkApplication).
In applications I've written I tend to either subclass both GtkApplication and GtkWindow or for single window quick-and-nasty applications just subclass GtkWindow. Your decision will depend on your applications needs.
Technical difference: There is also an important technical difference between how the two examples are implemented. The example with just a GtkWindow creates a new Gtk main loop for each instance of the program. The example with GtkApplication creates a single main loop attached to the first instance and each subsequent call to run(None) will request that the original instance create a new window (the new instance will then exit). Try opening up two terminals and running your application in each window, notice that one terminal will wait until all the windows have closed before becoming sensitive again. You can change this behaviour by using G_APPLICATION_NON_UNIQUE instead of G_APPLICATION_FLAGS_NONE.
The second code example looks unnecessary complicated to me, the first looks perfectly fine. The author of that second tutorial has put a link to another, even more simple example (Source):
from gi.repository import Gtk
window = Gtk.Window(title="Hello World")
window.connect("destroy", lambda w: Gtk.main_quit())
window.add(Gtk.Label("Hello World!"))
window.show_all()
Gtk.main()
There is nothing wrong with either approaches. You can use all the default widgets, not subclassing anything, like in the example above. Or you can subclass certain widgets, mainly as a way to give your code a nice structure and having re-usable custom/modified widgets in the end. That is all up to you.
The same applies to Qt and many other GUI frameworks, btw.
The second approach is better. It makes the application more integrated into the desktop and informs more about what it does or is meant to do. It also provides you with more tools to use with your application.
I think the first approach is just not up to date or something. The second one is really the preferred way.
You can see that the application Gnome-music is actually using the second approach with Gtk.Application usage. All the official Gnome apps are using Gtk.Application, and all Gtk application should be using it too.

are there any cross platform window toolkits for python that aren't made by crazy people?

well maybe crazy is a bit too strong of a word, but what I am asking is if there are any window toolkits out there that don't have me do this:
class MyApp(SomeWindowClass):
I really don't want to use a library made by someone who is so obsessed with objects that he/she thinks that there should be a class for the app (which there will only be one instance of, so I don't see why anyone would want to do that extra typing)
(btw, no offense intended towards anyone who agrees with the way these libraries are set up, I just really want to know if there is anything out there with a tad bit less objects)
In general GUI toolkits rely on having some form of event loop running, the Application class in these toolkits is generally in charge of that event loop and marshaling events from the underlying window manager. Sure they could call the class EventLoopManager or something, but you need it either way so its just a naming thing then. In some cases though some toolkits who often use events can occasionally be used without them, and then you certainly dont want it to be some automatic thing.
There is PyQT.
Tkinter has one object per window/dialog, not app, and requires no classes to get something painted on the screen. It does, however, have its own main loop (like all the other GUI libraries). Obligatory Hello World:
from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()
PyGTK another toolkit; which is python binding of Gtk. It is well structured with having excellent window and event loop system.
A typical example to show a window
import gtk
class Application:
def __init__(self):
self.window = gtk.GtkWindow(gtk.WINDOW_TOPLEVEL)
self.window.show()
if __name__ == "__main__":
app = Application()
gtk.mainloop()
Another recommendation is PyQt; which is python binding of Qt.
Typical hello world example is
import sys
from qt import *
app = QApplication(sys.argv)
myLabel = QLabel("Hello world!", None)
app.setMainWidget(myLabel)
myLabel.show()
app.exec_loop()
PyQt and PyGtk are widely used for rapid GUI development. From my experience pyGtk is poor in the online documentation/support compared to pyQt. But both are favorite of mine.
As you see with the answers above, GUI programming is almost always heavily object oriented, and there are good reasons for this: the graphical elements share a lot in terms of how they can be positioned within one-another, caring about whether the mouse pointer is over them etc. Furthermore, the C++ kits that qt, wx, gtk et al. wrap are already structured on a class/inheritance hierarchy, so you should not be surprised that the python wrappers are also.
If you want only simple GUI elements, then you may consider easyGUI (simple message boxes, text edit, choices), triatsUI (interactive object wrappers, primarily for controlling graphical objects) , which each solve some part of the GUI interactions without explicitly having you write GUI code.
For editing the values of fields in a record-like structure, you could also investigate GUIdata.
PS: there are various graphical tools out there to let you design your GUIs and link together some of the events, e.g., QtDesigner, that can help you avoid much of the tedious class definition code.

pyGame within a pyGTK application

What is the best way to use PyGame (SDL) within a PyGTK application?
I'm searching for a method that allows me to have a drawing area in the GTK window and at the same time being able to manage both GTK and SDL events.
I've never attempted it myself, but hearing plenty about other people who've tried, it's not a road you want to go down.
There is the alternative of putting the gui in pygame itself. There are plenty of gui toolkits built specifically for pygame that you could use. Most of them are rather unfinished, but there are 2 big, actively maintained ones: PGU and OcempGUI. The full list on the pygame site is here.
You may be interested in this message thread. Looks like they recommend against it.
PyGame works much better when it can manage its own window, or even better, use the whole screen. GTK has flexible enough widgets to allow creation of a drawing area.
This page may help, though, if you want to try it.
There's a simple solution that might work for you.
Write the PyGTK stuff and PyGame stuff as separate applications. Then from the PyGTK application call the PyGame application, using os.system to call the PyGame application. If you need to share data between the two then either use a database, pipes or IPC.
http://faq.pygtk.org/index.py?file=faq23.042.htp&req=show mentions it all:
You need to create a drawing area and set the environment variable SDL_WINDOWID after it's realized:
import os
import gobject
import gtk
import pygame
WINX = 400
WINY = 200
window = gtk.Window()
window.connect('delete-event', gtk.main_quit)
window.set_resizable(False)
area = gtk.DrawingArea()
area.set_app_paintable(True)
area.set_size_request(WINX, WINY)
window.add(area)
area.realize()
# Force SDL to write on our drawing area
os.putenv('SDL_WINDOWID', str(area.window.xid))
# We need to flush the XLib event loop otherwise we can't
# access the XWindow which set_mode() requires
gtk.gdk.flush()
pygame.init()
pygame.display.set_mode((WINX, WINY), 0, 0)
screen = pygame.display.get_surface()
image_surface = pygame.image.load('foo.png')
screen.blit(image_surface, (0, 0))
gobject.idle_add(pygame.display.update)
window.show_all()
while gtk.event_pending():
# pygame/SDL event processing goes here
gtk.main_iteration(False)
I tried doing this myself a while ago, and I never got it to work perfectly. Actually I never got it to work at all under Windows, as it kept crashing the entire OS and I ran out of patience. I continued to use it though as it was only important it ran on Linux, and was only a small project. I'd strongly recommend you investigate alternatives. It always felt like a nasty hack, and made me feel dirty.
The Sugar project has several Activities built with PyGTK and PyGame.
They wrote a support lib to achieve this, called Sugargame. You should be able to modify it for regular PyGTK apps instead of Sugar.
Here's a chapter in Sugar's development book about how to use it.
The lib allows for communicating events between GTK and PyGame.
Enjoy!

Categories

Resources