I posted on this topic earlier under “can’t find linker symbol for virtual table,” but I’ve pared the problematic code down to such an extent that I don’t see how the problem could be in my code — although I would be happy to hear where I went wrong…
I am running Windows 7, Qt 5.0.1 and MinGW.
When I execute the code in debug mode under QtCreator, I get the error
can't find linker symbol for virtual table for `QWidget' value
found `QMenuPrivate::popupGeometry(int) const' instead
as “Application Output” when I hit the breakpoint that I point out below in the code.
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
private slots:
void closeTextTab(int index);
void render2DMenuSlot();
private:
QMenu *actionMenu;
QAction *render2DAction;
QTabWidget *textTabs;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "codeitem.h"
#include "noteswidget.h"
#include "interpreter.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
render2DAction = new QAction(tr("&Render - 2D"),this);
connect(render2DAction,SIGNAL(triggered(bool)),this,SLOT(render2DMenuSlot()));
actionMenu = menuBar()->addMenu(tr("&Action"));
actionMenu->addAction(render2DAction);
}
void MainWindow::closeTextTab(int index)
{
}
void MainWindow::render2DMenuSlot()
{
// This is where the error manifests. Put a breakpoint here,
// before any of the code below executes, and you get the
// can't find linker symbol for virtual table for `QWidget' value
// error.
QWidget* curWidget = textTabs->currentWidget();
CodeItem *ti = qobject_cast<CodeItem*>(curWidget);
// The code below is non-functional garbage, but somehow removing
// it eliminates the error above. Moreover, even before I pared the underlying
// functionality away and the code below worked, I got the error above.
bool hasErrors = false;
QString errors;
Interpreter* interp = NULL;
try {
try {
interp = new Interpreter();
} catch (QString e) {
errors = e;
hasErrors = true;
}
if (hasErrors == false)
{
int* sigs = interp->nextStatementToSignals();
while (true)
{
delete sigs;
sigs = interp->nextStatementToSignals();
}
}
} catch (QString e) {
} catch (...) {
}
}
Now some .h files for three classes, all of which do essentially nothing, but eliminating them from the project also eliminates the error.
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include <QString>
class Interpreter
{
public:
Interpreter() throw(QString);
int* nextStatementToSignals();
};
#endif // INTERPRETER_H
#ifndef NOTESWIDGET_H
#define NOTESWIDGET_H
#include <QtWidgets>
class NotesWidget : public QWidget
{
Q_OBJECT
public:
explicit NotesWidget(QWidget *parent = 0);
};
#endif // NOTESWIDGET_H
#ifndef CODEITEM_H
#define CODEITEM_H
#include <QtWidgets>
#include "noteswidget.h"
class CodeItem : public NotesWidget
{
Q_OBJECT
public:
CodeItem();
};
#endif // CODEITEM_H
The three .cpp files that go with these classes don’t do anything either:
#include "interpreter.h"
Interpreter::Interpreter() throw(QString)
{
}
int* Interpreter::nextStatementToSignals()
{
return NULL;
}
#include "noteswidget.h"
NotesWidget::NotesWidget(QWidget *parent) : QWidget(parent)
{
}
#include "codeitem.h"
CodeItem::CodeItem() : NotesWidget()
{
}
For completeness, here’s the .pro file:
QT += core gui widgets
TARGET = vcnctest
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
codeitem.cpp \
noteswidget.cpp \
interpreter.cpp
HEADERS += mainwindow.h \
codeitem.h \
noteswidget.h \
interpreter.h
So, the program does nothing but open up an empty window with a single menu choice that routes to MainWindow::render2DMenuSlot(). As soon as the debugger hits the breakpoint at the start of that method, you get the error. It’s true that, as the code above stands, the method is garbage (the various pointers will be NULL), but that’s because I pared away every bit of functionality to get to cause of the error message. In any case, an error shouldn’t appear before you get to any of the code in the method.
I thought that there might be something going on in moc_window.cpp, so I put a breakpoint at the start of MainWindow::qt_static_metacall(). At the line
_c == QMetaObject::InvokeMetaMethod
I get a similar error:
can't find linker symbol for virtual table for `MainWindow' value
found `_q_ObjectMutexPool' instead
For reference, this is the complete method from moc_mainwindow.cpp:
void MainWindow::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
MainWindow *_t = static_cast<MainWindow *>(_o);
switch (_id) {
case 0: _t->closeTextTab((*reinterpret_cast< int(*)>(_a[1]))); break;
case 1: _t->render2DMenuSlot(); break;
default: ;
}
}
}
If I continue stepping into the case _t->render2DMenuSlot(), that’s were the original error appears:
can't find linker symbol for virtual table for `QWidget' value
found `QMenuPrivate::popupGeometry(int) const' instead
Yes, after paring away so much of the original program’s functionality, the program above is garbage, but these errors are out of left field. I don’t see how they could be due to anything other than a problem in the development framework.
↧