[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Removing __init_qt__ dependency on libgui

From: Alex Leach
Subject: Re: Removing __init_qt__ dependency on libgui
Date: Tue, 17 Nov 2020 10:27:18 +0000

From: John W. Eaton <jwe@octave.org>
Sent: 11 November 2020 18:52
To: Alex Leach <zander_leach@hotmail.com>; octave-maintainers@gnu.org <octave-maintainers@gnu.org>
Cc: jwe@octave.org <jwe@octave.org>
Subject: Re: Removing __init_qt__ dependency on libgui
If I understand correctly, you are proposing that the Qt plotting code +
Octave interpreter be usable without the Octave GUI?  That seems
reasonable, and I'm willing to work in that direction if you would like
to help with defining how these components should work together and be
Thanks for the response John, and apologies for the slow reply. Yes, you've hit the nail on the head, thanks and I'm glad that you think this is a reasonable proposition. I've had a good think about how I think these components could, or should be initialised, as had previously just been thinking of target objectives. I'll summarise these below.

As you note, however, the Qt graphics code is not usable
without the Octave interpreter.  So why not have your application start
the interpreter and interact with it to create plots using the Qt
graphics code?

This was exactly what I had originally been attempting, however I was really struggling to get it to work. My 'simple' example got larger and larger as I was implementing various derived classes (e.g. octave_link) in attempts to get figures to show with the qt backend, using the 5.2.0 release code. I finally got the figures to show, but none of the toolbar or menubar buttons worked. I then noticed the really small example file in the original QtHandles github repository (that I linked to in my previous email) and realised a small example might not need to be any more complicated than that. However, over the last year or two, dependencies on the main GUI have crept in to the qthandles code, so that when I ran the example (replacing octave_main with octave::cli_application, then executing that), loading __init_qt__ results in missing symbol errors from liboctgui. Linking against liboctgui would fix these issues, but I think should be unnecessary.

Anyway, looking ahead, and I'm really grateful you would be willing to help and work in this direction, I'll try to help with some definitions as you've asked for.


  • If I understood the way qthandles originally initialised, I think that made a lot of sense: as a package. It seems this happens automatically when compiled into the __init_qt__.oct module, through the PKG_ADD mechanism.
  • The PKG_ADD statement that was added to __init_qt__.cc would ideally be simpler. The `__octave_link_enabled__' and then `__event_manager_enabled__' tests would ideally be removed, if possible? The original test (in C++) that was still in the last version of __init_qt__.cc was `if (qApp) else error(...)'. Can we move that test into the PKG_ADD line, and load the package on that basis alone? There's already an `if (__have_feature__ ("QT") )` test, is this equivalent to `if(qApp)`?

So, overall, I think the mechanisms of initialisation were designed quite well in the first place. However, maybe the reason more tests were added and it got more complicated was that the extra event_manager / octave_link instances were absolutely required to be initialised outside of qthandles?

Event Manager / Octave Link

Looking at this more, I wonder if the event_manager definition can be simplified. In my app (when compiled against 5.2.0), a lot of the abstract functions were unnecessary, but I had to implement them regardless in order to subclass octave_link and enable it. As the interpreter initialises an event_manager anyway, can we just use that base definition and implement it as a dynamic callback manager, with just a few generic methods, in place of all the dialog and preference methods, something like:-

void event_manager::register_callback(std::string event_name, octave::octave_fcn cb);

octave_value_list event_manager::execute_callback(std::string event_name, octave_value_list args);

This sort of mechanism could get rid of a lot of the hardcoded _dialog methods, I think. Then, in the __init_qt__ extension (or any other extension), the appropriate callbacks are registered to override any set defaults. Is this something you think might work?

Objectives / Tests

  • I think if the original octave-qt tool (https://github.com/goffioul/QtHandles/blob/master/tool/octave-qt.cpp) could be compiled and run successfully, with the qt backend registered and used to display figures, that would make a good test. I don't know how to go about implementing this as part of the test suite, other than compiling and running it manually however.
  • The code in libgui/graphics should not need to include libgui/src. i.e. the CPPFLAG -Ilibgui/src should be removed.
  • uigetdir, uigetfile, uiputfile should call the qt backend once it's been initialised. Using the mechanism above, relevant callbacks could be registered?
To do

Other than the event manager stuff, I've tried making a stab at removing any dependency on libgui/src, and have made a fork on github, at https://github.com/alexleach/octave/tree/qthandles. I might have made a bit of a mess of the commit history (sorry!), but it seems to be working okay for launching a figure Container and Canvas.

What isn't working are the Qt widgets for uigetfile / uiputfile / uigetdir, I guess because I don't have an event manager. Another thing that isn't working (in this or the fltk backend), are the buttons for 'Show / Toggle / Hide grid on all axes'; these only affect the currently active axis, but I haven't looked into this much.

If there's anything else I can do to make this easier to implement, please let me know.

Best wishes,

reply via email to

[Prev in Thread] Current Thread [Next in Thread]