The subject line gives the error I get when running my program in debug mode in QtCreator. After stripping away nearly all of the original program, the error is due to something in the code below. Whatever is causing this error, it is “fragile,” meaning that things that seem to be unrelated affect whether or not the error appears. The program seems pretty innocuous and that’s what makes it so puzzling.
I am on Windows 7, 64 bit, running Qt 5.0.1.
Here’s main.cpp — the usual:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Next is mainwindow.cpp. This is where the error manifests itself, even it the cause is not here.
#include "mainwindow.h"
#include "codeitem.h"
#include "noteswidget.h"
#include "interpreter.h"
#include "bogusresult.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
createActions();
createMenus();
textTabs = new QTabWidget;
textTabs->connect(textTabs,SIGNAL(tabCloseRequested(int)),
this,SLOT(closeTextTab(int)));
CodeItem *codeWidget = new CodeItem();
(void) textTabs->addTab(codeWidget,"New");
setCentralWidget(textTabs);
}
MainWindow::~MainWindow()
{
}
void MainWindow::createActions()
{
render2DAction = new QAction(tr("&Render - 2D"),this);
connect(render2DAction,SIGNAL(triggered(bool)),this,SLOT(render2DMenuSlot()));
}
void MainWindow::createMenus()
{
actionMenu = menuBar()->addMenu(tr("&Action"));
actionMenu->addAction(render2DAction);
}
// Now a whole bunch of empty methods, which I omit for brevity.
// What's odd is that if I get rid of the function declarations in the .h file, and
// the (empty) function definitions here, then the error goes away. All of these
// functions return either void or bool, so they really don't have anything to
// do with the cause of the problem, even if they have something to
// do with how it manifests.
void MainWindow::render2DMenuSlot()
{
// This is where the error appears. I set the only breakpoint in the program at
// this line (before the line below is executed) and it says
// can't find linker symbol for virtual table for `QWidget' value
// found `QMenuPrivate::popupGeometry(int) const' instead
//
// Another weird thing is that if I get rid of just about any of the code below
// the first two lines, then the error disappears -- maybe the compiler is
// optimizing away the problem, whatever it is.
//
// None of the classes below, aside from CodeItem, actually do anything.
// Interpreter is defined as an empty do-nothing class, as is BogusResult. If you tried to
// actually run the code below, it would crash since all the pointers will be NULL,
// but that shouldn't affect the fact that you get an error at the very beginning.
QWidget* curWidget = textTabs->currentWidget();
CodeItem *ti = (CodeItem*) curWidget;
bool hasErrors = false;
QString errors;
Interpreter* interp = NULL;
try {
try {
interp = new Interpreter(QString(),true,1,NULL,NULL,NULL,0.0,0.0,0.0);
} catch (QString e) {
errors = e;
hasErrors = true;
}
if (hasErrors == false)
{
BogusResult* sigs = interp->nextStatementToSignals();
while (sigs->cmd->type != Statement::EndOfFile)
{
delete sigs;
sigs = interp->nextStatementToSignals();
}
}
} catch (QString e) {
} catch (...) {
}
}
mainwindow.h is:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtWidgets>
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void render2DMenuSlot();
// As noted in mainwindow.cpp, there are a bunch of irrelevant declarations made
// here too, which I omit. They have nothing to do with the problem, since the
// definitions are all empty, although removing them does make the error go away.
private:
void createActions();
void createMenus();
QMenu *actionMenu;
QAction *render2DAction;
QTabWidget *textTabs;
};
#endif // MAINWINDOW_H
Here are the .h and .cpp files for CodeItem. After stripping most of the code away to make the error easier to find, this is just a wrapper around NotesWidget. First, the .h file:
#ifndef CODEITEM_H
#define CODEITEM_H
#include <QtWidgets>
#include "noteswidget.h"
class CodeItem : public NotesWidget
{
Q_OBJECT
public:
CodeItem();
};
#endif // CODEITEM_H
And the .cpp file:
#include "codeitem.h"
CodeItem::CodeItem() : NotesWidget()
{
// Nothing to do...
}
Now noteswidget.h:
#ifndef NOTESWIDGET_H
#define NOTESWIDGET_H
#include <QtWidgets>
class NotesWidget : public QWidget
{
Q_OBJECT
private:
QTextEdit theText;
QTextEdit notes;
QHBoxLayout theLayout;
QVBoxLayout leftLayout;
public:
explicit NotesWidget(QWidget *parent = 0);
private slots:
void markDirty();
void contentsScrolled(int v);
};
#endif // NOTESWIDGET_H
And noteswidget.cpp
#include "noteswidget.h"
NotesWidget::NotesWidget(QWidget *parent) : QWidget(parent)
{
theText.verticalScrollBar()->connect(theText.verticalScrollBar(),
SIGNAL(valueChanged(int)),
this,SLOT(contentsScrolled(int)));
theText.connect(&theText,SIGNAL(textChanged(void)),this,SLOT(markDirty(void)));
leftLayout.addWidget(&notes);
theLayout.addLayout(&leftLayout);
theLayout.addWidget(&theText);
this->setLayout(&theLayout);
}
void NotesWidget::contentsScrolled(int v)
{
}
void NotesWidget :: markDirty()
{
}
This is for the code. After stripping things down, there’s not much left. I don’t see a problem with any of this, but I am new to Qt.
↧