Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt5 tabwidget - addwidget exception thrown read access violation



  • Any ideas about why this is occurring? New to Qt, so thanks in advance for the help.

    QWidget* centralWidget = new QWidget();
    QTabWidget* tabWidget = new QTabWidget(centralWidget);
    tabWidget->setTabsClosable(false);
    
    this->setCentralWidget(centralWidget);
    
    
    
    QWidget* logTab = new QWidget();    
    QTextEdit* logOutput = new QTextEdit();
    logOutput->setReadOnly(true);
    logOutput->setLineWrapMode(QTextEdit::NoWrap);
    QFont* font = new QFont();
    font->setFamily("Courier");
    font->setPointSize(10);
    
    QVBoxLayout* tabLayout = new QVBoxLayout();
    tabLayout->addWidget(logOutput);
    logTab->setLayout(tabLayout);
    
    tabWidget->addTab(logTab, tr("Log"));
    
    

    On the addtab it gives exception thrown read access violation, callstack below:

    Qt5Widgetsd.dll!QTabWidget::insertTab(int index, QWidget * w, const QIcon & icon, const QString & label) Line 472   C++
    Qt5Widgetsd.dll!QTabWidget::insertTab(int index, QWidget * w, const QString & label) Line 454   C++
    Qt5Widgetsd.dll!QTabWidget::addTab(QWidget * child, const QString & label) Line 399 C++
    

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Is that code all in the same method ?
    Please show the complete stack trace.



  • Here is the complete code:

    Rommer::Rommer(QWidget *parent)
    	: QMainWindow(parent)
    {
    	this->uiSetup();
    }
    
    void Rommer::uiSetup()
    {
    	QAction* newdb = new QAction("&New", this);
    	newdb->setShortcut(tr("CTRL+N"));
    	newdb->setStatusTip("New Mame Db");
    	connect(newdb, &QAction::triggered, this, &Rommer::add_db);
    
    	QAction* quit = new QAction("&Quit", this);
    	quit->setShortcut(tr("CTRL+Q"));
    	quit->setStatusTip("Close Program");
    	connect(quit, &QAction::triggered, qApp, QApplication::quit);
    
    	file = menuBar()->addMenu("&File");
    	file->addAction(newdb);
    	file->addAction(quit);
    
    	QWidget* centralWidget = new QWidget();
    	QTabWidget* tabWidget = new QTabWidget(centralWidget);
    	tabWidget->setTabsClosable(false);
    
    	this->setCentralWidget(centralWidget);
    
    	this->addLogTab();
    
    	this->statusBar();
    	this->setWindowTitle("Rommer");
    	this->showMaximized();
    }
    
    int Rommer::tabFindByName(string name)
    {
    	int rc = -1;
    	int noTabs = tabWidget->count();
    	for (int i = 0; i < noTabs; i++) {
    		QString tabname = tabWidget->tabText(i);
    		if ( tabname.toStdString() == name) {
    			rc = i;
    			break;
    		}
    	}
    	return rc;
    }
    
    bool Rommer::tabSelectByName(string name)
    {
    	bool rc = false;
    	int tabNo = tabFindByName(name);
    	if (tabNo != -1) {
    		tabWidget->setCurrentIndex(tabNo);
    		rc = true;
    	}
    	return rc;
    }
    
    bool Rommer::tabDeleteByName(string name)
    {
    	bool rc = false;
    	int tabNo = tabFindByName(name);
    	if (tabNo != -1) {
    		tabWidget->removeTab(tabNo);
    		rc = true;
    	}
    	return rc;
    }
    
    void Rommer::addLogTab()
    {
    	QWidget* logTab = new QWidget();
    	
    	QTextEdit* logOutput = new QTextEdit();
    	logOutput->setReadOnly(true);
    	logOutput->setLineWrapMode(QTextEdit::NoWrap);
    	QFont* font = new QFont();
    	font->setFamily("Courier");
    	font->setPointSize(10);
    
    	QVBoxLayout* tabLayout = new QVBoxLayout();
    	tabLayout->addWidget(logOutput);
    	logTab->setLayout(tabLayout);
    
    	tabWidget->addTab(logTab, tr("Log"));
    	
    	logOutput->moveCursor(QTextCursor::End);
    	logOutput->setTextColor(QColor(0, 0, 255));
    	logOutput->insertPlainText("Log Started\n\n");
    	logOutput->verticalScrollBar();
    }
    
    void Rommer::add_db()
    {
    
    }
    
    And here is the complete callstack:
    
    

    Qt5Widgetsd.dll!QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>>::operator->() Line 118 C++
    Qt5Widgetsd.dll!qGetPtrHelper<QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>>>(const QScopedPointer<QObjectData,QScopedPointerDeleter<QObjectData>> & ptr) Line 1038 C++
    Qt5Widgetsd.dll!QTabWidget::d_func() Line 175 C++
    Qt5Widgetsd.dll!QTabWidget::insertTab(int index, QWidget * w, const QIcon & icon, const QString & label) Line 472 C++
    Qt5Widgetsd.dll!QTabWidget::insertTab(int index, QWidget * w, const QString & label) Line 454 C++
    Qt5Widgetsd.dll!QTabWidget::addTab(QWidget * child, const QString & label) Line 399 C++
    QtGuiApplication1.exe!Rommer::addLogTab() Line 89 C++
    QtGuiApplication1.exe!Rommer::uiSetup() Line 33 C++
    QtGuiApplication1.exe!Rommer::Rommer(QWidget * parent) Line 6 C++
    QtGuiApplication1.exe!main(int argc, char * * argv) Line 7 C++
    QtGuiApplication1.exe!WinMain(HINSTANCE__ * formal, HINSTANCE * __formal, char * __formal, int __formal) Line 97 C++
    [External Code]



  • remove QFont* font = new QFont(); font->setFamily("Courier"); font->setPointSize(10);


  • Lifetime Qt Champion

    @jonndoe47 said in Qt5 tabwidget - addwidget exception thrown read access violation:

    QTabWidget* tabWidget = new QTabWidget(centralWidget);

    I guess you have a class member that has the same name ?

    If so you are shadowing it and thus in your other methods you are using an uninitialized pointer.



  • I don't know whay you asked me to delete to QFont, made no difference.

    tabwidget is the member variable, no member method in the class. Here's the class def from the header file.

    class Rommer : public QMainWindow
    {
    	Q_OBJECT
    
    public:
    	Rommer(QWidget *parent = Q_NULLPTR);
    
    private:
    	QMenu* file;
    	QAction* newdb;
    	QAction* quit;
    	QTabWidget* tabWidget;
    	QWidget* logTab, centralWidget;
    	QTextEdit* logOutput;
    	void uiSetup();
    	void add_db();
    	int tabFindByName(string name);
    	bool tabSelectByName(string name);
    	bool tabDeleteByName(string name);
    	void addLogTab();
    };
    
    
    

    Still have no idea what this error is. Qt version is 5.14.2 installed it for MSVC 2017 64bit.

    And I am a bit new to C++ (but have programmed for 30+ yrs) but I've never heard the term shadow ??? Thanks for your help in advance.


  • Lifetime Qt Champion

    Well, in fact your are shadowing all your members variable.

    Shadowing means that you use the same name for a function scoped variable that you can find in your class member variable. Therefore, you think you initialized your member variables while in fact you have variables valid only for the duration of the method.



  • I just read up on Shadowing. I'm a bit confused can you just give me one example of my code and then the corrected way to do it please ? I'm new to C++ so I sort of understand but have not come up against this ? All the code I've written I've defined the vars as private in the .h file. I'm sort of lost here.


  • Lifetime Qt Champion

    Your uiSetup method is the exact example of that.

    Remove all the type declarations before the variables that match class members and you should be good to go.



  • Thank you so much, I feel really stupid but now I realise what you mean. Arghh. Also this line:

    QWidget* logTab, centralWidget;
    split to two lines, as it caused weirdness.... Works now, thank you for explaining to a newb what was wrong. Really appreciate it.



  • @jonndoe47 said in Qt5 tabwidget - addwidget exception thrown read access violation:

    QWidget* logTab, centralWidget;

    Do you also realise that in C/C++ this declares centralWidget as being a QWidget, not a QWidget*? Despite the spacing hinting otherwise. It can be clearer to put the * next to the variable being defined rather than after the type. I'm guessing you intended:

    QWidget *logTab, *centralWidget;

    ?



  • Aha, that is why I was getting that odd behaviour!!!! Thanks. Sorry about the late reply. I just saw your answer, much appreciated. Have too admit, though I am enjoying coding in C++ I find it an utter (expletive) I've never coded in C before either did a quite a bit of pascal, cobol, clipper, python, php etc. C++ is a pain to code, but worth it for the speed.



  • @jonndoe47
    I am not aware of a Qt interface from COBOL... ;-)

    Make sure you use Qt Creator for writing your C++ code, the autocompletion for calling Qt methods/parameters is invaluable, especially when learning.



  • Ack, I hated COBOL. I don't use Qt Creator and write all the code from scratch. I suppose I have to learn it sometime. But I use Visual Studio to write in so it's got auto complete for that anyway. Plus, yes I know using Qt Creator means I wouldn't have made those glaring bad errors , but then I learn something, finding and tracking bugs down and asking questions gets you to understand the code a lot more, this is my personal opinion and it's the best way that works for me.


Log in to reply