我很难尝试从Vala / C到Python的路径并再次退回。我所有的google-fu都引领着我。 我想使用Vala编写API,然后从Python(或者可能是Gnome Javascript)中使用它。
使用Clutter作为我的例子(也可能是GTK + 3小部件)这里是我的问题:我如何 -
编写一个自定义的Actor,点击后会:
在Python中,我创建了一个舞台,并且(不知何故 - 通过GI魔术)创建了我的新Actor。我做所有Python的东西来设置它,我连接到相同的按钮释放'事件(我猜......)
a)Vala处理程序运行然后运行Python吗? (按顺序,或者根本不用。)
b)我是否必须在Vala处理程序中做一些特殊的事情 - 比如返回true,或者为Python发出一些新的信号来接收?
让我们说演员被称为V.我如何:V.set_col(' red')(在Python中)让它运行Vala set_col方法,传递Python字符串? (我怀疑这是GI下的自动化,但我不确定。)
Vala actor -- event --> handler (in Vala) --> handler (in Python) with data
Vala method <--- method call with args from Python
我也感谢任何链接,谢谢。
答案 0 :(得分:1)
我明白了。下面的代码就像这样:
运行./build,它应该研磨voodoo并运行test.py文件。
您应该看到一个Clutter窗口。单击红色方块并观察控制台barf。
: - d
HTH。
#!/bin/bash
#
# Script borrowed from Tal Liron at:
# https://github.com/tliron/pygobject-example
#
# I did these to get this script to work:
#
# apt-get install libgirepository1.0-dev
# apt-get install gobject-introspection
#
echo "Cleaning..."
rm -rf tmp
rm -rf lib
rm -rf type
rm -f test
mkdir tmp
mkdir lib
mkdir type
echo "Building Vala library..."
# Note 1: Ubuntu package for valac: valac-0.14
# Note 2: Generates broken gir if --gir= has a directory prefixed to it
# Note 3: The -X switches for gcc are necessary!
# Note 4: The generated gir will include GObject-2.0. That gir is
# included in Ubuntu package: libgirepository1.0-dev
valac \
--pkg clutter-1.0 \
--library=Palelib \
--directory=tmp \
--gir=Palelib-1.0.gir \
--output=libpalelib.so \
-X -shared \
-X -fPIC \
redsquare.vala
mv tmp/libpalelib.so lib
mv tmp/Palelib-1.0.gir type
# Note: We cannot generate C code and compile in the same call
# (We don't need the C code to run the test, but we are curious
# as to what Vala is generating. The resulting code will be in
# logging.c)
#valac \
#--ccode \
#redsquare.vala
echo "Building typelib..."
# Note 1: Ubuntu package for g-ir-compiler: gobject-introspection
# Note 2: The --shared-library switch is really only necessary when using
# the gir produced by valac, because it does not include the
# 'shared-library' attribute in <namespace> tag.
g-ir-compiler \
--shared-library=libpalelib.so \
--output=type/Palelib-1.0.typelib \
type/Palelib-1.0.gir
echo "Test Python..."
# Note 1: Ubuntu's default path for typelib files seems to be:
# /usr/lib/girepository-1.0/.
# Note 2: It is also possible to programmatically change the
# GI_TYPELIB_PATH environment var in Python (os.environ API).
# If you do so, make sure to set it before importing from
# gi.repository.
LD_LIBRARY_PATH=lib \
GI_TYPELIB_PATH=type \
./test.py
namespace Palelib {
public class RedSquare : Clutter.Actor {
//private vars
private Clutter.Canvas _canvas;
private int[] _col = { 255, 0, 0 };
//Constructor - Needs to be called explicitly from Python by .new()
public RedSquare() {
stdout.printf( "RedSquare constructor.\n" );
_canvas = new Clutter.Canvas();
_canvas.set_size(300,300);
this.set_size(300,300);
this.set_content( _canvas );
//Connect to the draw signal.
_canvas.draw.connect(drawme);
//Make it reactive and connect to the button-press-event
this.set_reactive(true);
this.button_press_event.connect( cleek );
}
//Button press signal handler
private bool cleek ( Clutter.ButtonEvent evt ) {
stdout.printf("Vala cleek() has run!\n");
this._col = {0,255,0}; //Just change the colour
this.redraw("from Vala");
//return true; //Stops the signal here. Python won't get it.
return false; //Lets the signal carry on going (to Python).
}
//Draws the Cairo art to the canvas
private bool drawme( Cairo.Context ctx, int w, int h) {
stdout.printf("drawme test.\n");
ctx.set_source_rgb(this._col[0],this._col[1],this._col[2]);
ctx.rectangle(0,0,300,300);
ctx.fill();
return true;
}
//Redraw - forces invalidate which trips the draw event
//Am gonna call this directly from Python too!
public void redraw(string? thing) {
thing = thing ?? "from null"; //tests for null or else
stdout.printf( "redraw test %s.\n", thing );
this._canvas.invalidate();
}
} //end RedSquare class
} //end namespace
#!/usr/bin/env python3
"""
Tests the instance of our Vala actor.
I expect to see a red square on the white stage.
(It can be clicked.)
"""
import sys
from gi.repository import Palelib, Clutter
Clutter.init(sys.argv)
stage = Clutter.Stage()
stage.set_size(800, 400)
stage.set_title("Blah blah")
stage.connect('destroy', lambda x: Clutter.main_quit() )
# Make our Object:
rs = Palelib.RedSquare.new() #Note the .new() call. Yuck.
print(rs)
#print(dir(rs)) # See that it is an Actor object.
rs.set_position(100,100)
stage.add_child(rs)
#Force rs to appear. Calls a Vala method and passes a string.
rs.redraw("from Python")
"""
# Crud for testing:
r1 = Clutter.Rectangle()
r1.set_size(50,50)
r1.set_position(0,0)
damnweird = Clutter.Color.new(0,0,0,255)
r1.set_color( damnweird )
stage.add_child(r1)
"""
"""
Let's get an event going from Python!
Because the RedSquare actor is *already* listening
to a button-press-event (in Vala) this is the second
such event it will obey.
I *think* it happens after the vala cleek() method runs.
If you |return true| in cleek(), then this does NOT run,
so that implies that Python is happening second in the chain.
"""
def gogo( a, evt ):
print ("Hello from gogo. %s %s" % (a,evt))
rs.connect("button_press_event", gogo)
stage.show_all()
Clutter.main()