Using MainWindow in an Extension

Hi all,

I’m currently working on an Avogadro extension. It should be able to control
most of the Avogadro functionnalities (camera, open file, copy/paste, select
a tool, add hydrogen, …) with an external controller.
I found the Navigate class to use the camera, and it is ok. But for some
other points, I need help:
I think I can call every other functionnalities by using the MainWindow
instance, am I correct?
I tried to get the MainWindow instance by QObject_casting the parent() of
the extension in a loop in the constructor. The QObject_cast
works, but the casting in MainWindow fails.

if (!m_mainwindow) {
QObject mainwindow = this;
while (mainwindow && !qobject_cast<MainWindow
>(mainwindow)) {
mainwindow = qobject_cast<QWidget*>(mainwindow->parent());
}
m_mainwindow = qobject_cast<MainWindow*>(mainwindow);
}

The error is :
In function Avogadro::MainWindow* qobject_cast<Avogadro::MainWindow*>(QObject*)': /usr/include/qt4/QtCore/qobject.h:366: undefined reference toAvogadro::MainWindow::staticMetaObject’

MainWindow is a QObject, I don’t understand why the QObject_cast doesn’t
work.
Do you know why? (or maybe you know a better idea to resolve my problem)

Regards,

RM

On Fri, Jul 8, 2011 at 11:07 AM, Rodolf Meyer rodolf.meyer@gmail.com wrote:

Hi all,
I’m currently working on an Avogadro extension. It should be able to control
most of the Avogadro functionnalities (camera, open file, copy/paste, select
a tool, add hydrogen, …) with an external controller.
I found the Navigate class to use the camera, and it is ok. But for some
other points, I need help:
I think I can call every other functionnalities by using the MainWindow
instance, am I correct?
I tried to get the MainWindow instance by QObject_casting the parent() of
the extension in a loop in the constructor. The QObject_cast
works, but the casting in MainWindow fails.
if (!m_mainwindow) {
QObject mainwindow = this;
while (mainwindow && !qobject_cast<MainWindow
>(mainwindow)) {
mainwindow = qobject_cast<QWidget*>(mainwindow->parent());
}
m_mainwindow = qobject_cast<MainWindow*>(mainwindow);
}

I’ve used this method to get the QMainWindow object in the
crystallography extension, but only to get access to the dockwidget
methods, which are implemented in QMainWindow (not
Avogadro::MainWindow). I do not think what you are trying to do is
possible (at least not in a reliable way) since the
Avogadro::MainWindow class is not available to extensions, as it is
not in libavogadro and its headers are not installed.

However, some of the functionality you want is possible in other ways:

Files can be opened by using Avogadro::MoleculeFile to create a
Molecule instance, which can be loaded in the main window by emitting
the moleculeChanged(Molecule*) signal from your extensions.

Copy/paste can be implemented in an extension by modifying/reading the
molecule that is passed to the extension in the
Avogadro::Extension::setMolecule slot and using QClipboard and
associated classes.

AFAIK, tool selection is not possible from within an extension, though
it certainly would be useful!

“Add hydrogen” and most other molecule modification can be performed
by handling the setMolecule virtual function to store the pointer to
the current molecule, and then modifying it. Calling
Molecule::update() when you’re done modifying the molecule will force
the GL widgets that are drawing the molecule to refresh.

Hope this helps,

Dave

The error is :
In function Avogadro::MainWindow* qobject_cast<Avogadro::MainWindow*>(QObject*)': /usr/include/qt4/QtCore/qobject.h:366: undefined reference to Avogadro::MainWindow::staticMetaObject’
MainWindow is a QObject, I don’t understand why the QObject_cast doesn’t
work.
Do you know why? (or maybe you know a better idea to resolve my problem)
Regards,
RM


All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security
threats, fraudulent activity, and more. Splunk takes this data and makes
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
avogadro-devel List Signup and Options

On Jul 8, 2011, at 11:20 AM, David Lonie wrote:

However, some of the functionality you want is possible in other ways:

Right, and we’d be open to adding more signals/slots if needed to access the main window.

AFAIK, tool selection is not possible from within an extension, though
it certainly would be useful!

Sure it is. For example:
widget->toolGroup()->setActiveTool(“Navigate”);

The tool selection is handled by the widget, not the MainWindow class.

Cheers,
-Geoff

Hi,

Thanks for your answers, it helps me a lot.

2011/7/8 Geoffrey Hutchison geoff.hutchison@gmail.com

Right, and we’d be open to adding more signals/slots if needed to access the main window.

I think this option could be very useful. The extension I’m working on
should allow to use Avogadro with an external controller in order to
improve the usability. By accessing the main windows, my goal was to
make any option of the menu bar, the tool bar and maybe the dock
widgets available to the extension. And this way give the ability to
bind the controller buttons to some functionalities of Avogadro.

I’ll give you more information later depending on the project progress.

Regards,

RM

I think this option could be very useful. The extension I’m working on
should allow to use Avogadro with an external controller in order to
improve the usability. By accessing the main windows, my goal was to
make any option of the menu bar, the tool bar and maybe the dock
widgets available to the extension.

Well, this is off the top of my head – I haven’t checked code yet. I’d be curious if QtScript or the Qt accessibility framework make this easier.

  1. Tool bar is easy – you can already switch tools with code.

foreach(Tool *tool, GLWidget::current->toolGroup()->tools())
{
qDebug() << tool->identifier();
}

// or something like this
GLWidget::current()->toolGroup()->setActiveTool(“Manipulate”);

  1. Accessing the MainWindow and Dock widgets can occur through qApp():

    foreach( QWidget *widget, qApp->topLevelWidgets() ) {
    if ( qobject_cast<MainWindow *>( widget ) )
    mainWindowCount++;
    }

All widgets can be accessed through the Qt meta-object system:

http://doc.qt.nokia.com/4.7/qmetaobject.html#methodCount
http://doc.qt.nokia.com/4.7/qmetaobject.html#invokeMethod

If you can tell us a little more about what you’re planning in the extension, it might be easier for us to give specifics.

Hope that helps,
-Geoff