Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Using DBUS and GTK in one perl program
Perl is by far the language I have the most experience with, and I have (big) parts of the functionality I want in the new program in existing programs. So I'm looking for a way to do this in perl, but I know other languages so a good guide to do what I want in another language might be usable.
Both the DBUS and GTK tutorials I have found say to "end" (there's some cleanup to do afterwards, but that's quite irrelevant) your program with calling their main loop, for DBUS:
my $reactor=Net::DBus::Reactor->main();
# Now start the reactor loop. This will keep this program alive until it is
# killed by a signal.
$reactor->run();
and for GTK:
# Creating and run the Gtk3::Application
my $app = Gtk3::Application->new('app.id', 'flags-none');
...
$app->run(\@ARGV);
But what to do if I want to do both in one program?
- Is there an obvious way to do it?
- Do better (more recent?) tutorials exist?
- In searching for how to do this I came across something called GDLIB, is that the solution, and do any good tutorial on using that exist?
1 answer
I haven't developed with Perl or DBUS myself (but I have used GTK), so I can only give an answer in general terms rather than specific details.
In most, if not all, GUI frameworks, the "run" or "main" method is simply a convenience that is used by most apps to hand over control of the main event-handling loop to the framework. If you need more control, you can implement the loop yourself.
As the GLib docs describe here:
Single iterations of a
GMainContext
can be run withg_main_context_iteration()
. In some cases, more detailed control of exactly how the details of the main loop work is desired, for instance, when integrating theGMainLoop
with an external main loop. In such cases, you can call the component functions ofg_main_context_iteration()
directly. These functions areg_main_context_prepare()
,g_main_context_query()
,g_main_context_check()
andg_main_context_dispatch()
.
This is for the GLib C API, but I would assume that any decent-quality language binding would expose these same functions. The GTK functionality is built on top of GLib, and offers similar functions like gtk_main_iteration()
.
What this means in practice is that if you need two main loops, such as the GTK + DBUS example you describe, at least one of those loops is going to need to be implemented manually in your code, rather than handed over to a "main" or "run" function.
This could be achieved by:
- Writing the entire loop manually, interleaving methods like
gtk_main_iteration()
and whatever DBUS offers as an equivalent, ensuring you handle return values, check for pending events or whatever else is required by the API when handling a main loop yourself. - Using
gtk_main()
to hand over control to GTK, then using either timeouts or idle callbacks to periodically invoke your code to receive DBUS events and iterate the DBUS main loop. This may be slightly easier because you only have to implement one of the main loops manually, although you'll have less control over precisely when your event-handling code gets called.
1 comment thread