I am trying follow the instructions published here:
https://www.linux.org/threads/c-tutorial-create-qt-applications-without-qtcreator.18409/
but in a PC running Windows 10, to build a Qt application createdwith the Atom editor. I have this 3 files in my project right now:
qt_main.cpp
#include <QtWidgets>
#include "mainwidget.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWidget w;
w.show();
return a.exec();
}
mainwidget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
class QPushButton;
class QTextBrowser;
class MainWidget : public QWidget
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = 0);
~MainWidget();
private:
QPushButton* button_;
QTextBrowser* textBrowser_;
};
#endif // MAINWIDGET_H
mainwidget.cpp
#include <QtWidgets>
#include "mainwidget.h"
MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
button_ = new QPushButton(tr("Push Me!"));
textBrowser_ = new QTextBrowser();
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(button_,0,0);
mainLayout->addWidget(textBrowser_,1,0);
setLayout(mainLayout);
setWindowTitle(tr("Connecting buttons to processes.."));
}
MainWidget::~MainWidget()
{
delete button_;
delete textBrowser_;
}
I execute this commands, in sequence:
qmake -project
add `QT += widgets` to the qt_main.pro file generated
qmake qt_main.pro
make
After that, the EXE file is generated without error, but when I try run it, I got the error:
"The procedure entry point _ZN10QArrayData10deallocateEPS_jj could not be located in the dynamic link library etc."
I try follow the suggested on the comments for the question:
QArrayData error, linking Qt libraries with CMake
and check my PATH. right now, the only directory containing qt DLLs is the one:
C:\Qt\Qt5.14.0\5.14.0\mingw73_64\bin
(this directory was createwd by the Qt offline installer).
Anyone can give a hint of how to solve this issue?
Related
I am trying to build a basic Qt Application with the Meson Build System on my Mac (using macOS Sierra), following the tutorial on http://mesonbuild.com/samples.html.
My meson.build file looks like this:
project('qt5 demo', 'cpp',
default_options : ['cpp_std=c++11'])
qt5_dep = dependency('qt5', modules : ['Core', 'Gui', 'Widgets'])
# Import the extension module that knows how
# to invoke Qt tools.
qt5 = import('qt5')
prep = qt5.preprocess(moc_headers : 'mainWindow.h',
ui_files : 'mainWindow.ui')
executable('qt5app',
sources : ['main.cpp', 'mainWindow.cpp', prep],
dependencies : qt5_dep,
cpp_args : '-std=c++11')
I have a small test program consisting of only four files: main.cpp, mainwindow.h, mainwindow.cpp, and mainwindow.ui.
The source code is as follows.
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 <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
The program compiles and executes as expected when I use qmake as a build system using the following qmake-file:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = QtDesigner
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
When I execute
meson build
it works fine, except for the warning:
WARNING: rcc dependencies will not work reliably until this upstream issue is fixed:
https://bugreports.qt.io/browse/QTBUG-45460
It also compiles without errors, when I switch to the build directory and call
ninja
but when I execute the program I get the following error:
dyld: Library not loaded: #rpath/QtCore.framework/Versions/5/QtCore
Referenced from:
/Users/<myname>/code/C++/QtDesignerCode/build/./qt5app
Reason: image not found
Abort trap: 6
It seems like the linker cannot find the libraries? Which is weird, as in Qt Creator (using qmake) the source code compiles fine.
Thanks in advance for any help.
Do the following in the build dir
mesonconf -Dcpp_std=c++11
or, set the default language version in your meson.build file
I am trying to make the code found on this page compile. All I want to do is replicate what that page describes. I keep getting an error that says:
main.cpp:13: error: undefined reference to `vtable for myMainWindow'
Here's my code, which is pretty much exactly like the code on that page:
main.cpp
#include <QApplication>
#include <QDialog>
#include <QWidget>
#include <QGridLayout>
#include <QPushButton>
#include <QMainWindow>
#include <QBitmap>
class myMainWindow : public QMainWindow
{
public:
myMainWindow():QMainWindow()
{
setMask((new QPixmap("saturn.png"))->mask());
QPalette* palette = new QPalette();
palette->setBrush(QPalette::Background,QBrush(QPixmap("saturn.png")));
setPalette(*palette);
setWindowFlags(Qt::FramelessWindowHint);
QWidget *centralWidget = new QWidget(this);
QGridLayout *layout = new QGridLayout();
centralWidget->setLayout(layout);
QPushButton* button1 = new QPushButton("Button 1");
button1->setFixedSize(80,50);
layout->addWidget(button1,0,0);
setCentralWidget(centralWidget);
};
~myMainWindow();
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
myMainWindow *window = new myMainWindow();
window->resize(600, 316);
window->show();
return app.exec();
}
I read up on why this might be occurring and saw that it was something about needing to have the class defined in a header file. How would I go about doing that correctly given this code?
Aside from missing the destructor definition, you are also missing the Q_OBJECT macro, which is mandatory for all QObject derived classes. If you had that, you'd get another error about the MOC generated files, when you define QObject derived classes in main.cpp you need to include the MOC file manually. This is not the case if you use a dedicated h and cpp file for QObject derived classes.
As stated in the comments: The missing function body for ~myMainWindow() was the problem.
I Started learning Qt (5.5) a couple of days ago, and I recently got stuck on something when working with the connect function, specifically the SLOT parameter. I'm calling a member function from the same class that the connect function is called in, but when the SLOT function is triggered it acts like it's creating a new class object. It worked initially when I kept everything in the same class, but this problem popped up when I tried implementing a hierarchy. I wrote a short program to demonstrate my problem.
Main.cpp
#include <QApplication>
#include "MainWindow.h"
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
MainWindow QtWindow;
QtWindow.show();
return app.exec();
}
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QGridLayout>
#include "TopWidget.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QMainWindow *parent = 0);
private:
QWidget *mainWidget;
QGridLayout *mainLayout;
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
MainWindow::MainWindow(QMainWindow *parent) : QMainWindow(parent){
mainWidget = new QWidget(this);
mainLayout = new QGridLayout(mainWidget);
setCentralWidget(mainWidget);
TopWidget tWidget(this);
mainLayout->addWidget(tWidget.topWidget, 0, 0);
}
TopWidget.h
#ifndef TOPWIDGET_H
#define TOPWIDGET_H
#include <stdlib.h>
#include <QWidget>
#include <QPushButton>
#include <QGridLayout>
#include <QDebug>
#include <QErrorMessage>
class TopWidget : public QWidget
{
Q_OBJECT
public:
TopWidget(QWidget *parent);
QWidget *topWidget;
private:
QGridLayout *wLayout;
QPushButton *Button;
int memVar1;
int memVar2;
private slots:
void testConnect();
//void SlotWithParams(int a, int b);
};
#endif // TOPWIDGET_H
TopWidget.cpp
#include "TopWidget.h"
TopWidget::TopWidget(QWidget *parent) : QWidget(parent){
topWidget = new QWidget(parent);
wLayout = new QGridLayout(topWidget);
memVar1 = 123;
memVar2 = 321;
Button = new QPushButton("Click Me", topWidget);
connect(Button, &QPushButton::clicked, [=](){ TopWidget::testConnect(); });
}
void TopWidget::testConnect(){
qDebug("Button worked");
if(memVar1 != 123 || memVar2 != 321){
qDebug("Linking failed");
}else{
qDebug("Linking success");
}
}
Since I just started with Qt, I don't have a good feel for what's "proper" Qt code, and what I should avoid, so tips in that direction are also appreciated. The following is the qmake file, if that's important.
CONFIG += c++11
CONFIG += debug
CONFIG += console
QT += widgets
QT += testlib
SOURCES += main.cpp
SOURCES += MainWindow.cpp
SOURCES += TopWidget.cpp
HEADERS += MainWindow.h
HEADERS += TopWidget.h
Release:DESTDIR = bin/Release
Release:OBJECTS_DIR = obj/Release
Release:MOC_DIR = extra/Release
Release:RCC_DIR = extra/Release
Release:UI_DIR = extra/Release
Debug:DESTDIR = bin/Debug
Debug:OBJECTS_DIR = obj/Debug
Debug:MOC_DIR = extra/Debug
Debug:RCC_DIR = extra/Debug
Debug:UI_DIR = extra/Debug
When I run the program in debug mode and press the button, it outputs "Button worked" indicating the link to the function was successful, but then outputs "Linking failed" indicating that a new object was created rather than taking the old one. My knowledge of C++ is patchy, since I only pick up what I need to, and I spent hours yesterday trying to fix this, so forgive me if the fix is something ridiculously easy, but I've mentally exhausted myself over this.
The problem comes from this line:
TopWidget tWidget(this);
You are allocating tWidget on the stack, and it gets destroyed just at the end of the MainWindow constructor.
Replace by:
TopWidget * tWidget = new TopWidget(this);
Also, you should replace your connect line by this one
connect(Button, &QPushButton::clicked, this, &TopWidget::testConnect);
It appears that your slot is called even after the TopWidget is destroyed. Qt normally disconnects connections when sender or receiver are destructed, but it's not able to do that when you connect to a lambda.
And finally, you are doing something weird. What is the purpose of your TopWidget class besides just creating another widget and receiving signals on its slot? You never add the TopWidget to any layout, but just its child. TopWidget is never shown, so it should rather derive from QObject only.
I am trying to make a app using qt 5.4.1(and qwt 6.1.2).Here is my environment:
Windows 7 x64
visual studio 2012
Qt5.4.1 static
qwt6.1.2
and I have built qwt with my Qt static libs successfully.
I creat a widget class inherited from QwtPlot,and I creat a mainWindow which has a object of that widget. Then I build the project.
However,there is a runtime error:QWidget: Must construct a QApplication before a QWidget.
This is my widget class inherited from QwtPlot:
#pragma once
#include <QWT/qwt_plot.h>
#include <QWT/qwt_plot_curve.h>
class DrawWidget: public QwtPlot
{
public:
DrawWidget(QWidget *parent );
~DrawWidget(void);
};
DrawWidget::DrawWidget(QWidget *parent )
: QwtPlot( parent ),
carve(NULL)
{
}
And the follow is my mainWindow class:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "DrawWidget.h"
#include <QtWidgets/QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
DrawWidget *drawWidget;
};
#endif // MAINWINDOW_H
MainWindow::MainWindow(QWidget *parent)
:QMainWindow(parent)
{
QWidget *widget = new QWidget(this);
this->setCentralWidget(widget);
QHBoxLayout *mainLayout = new QHBoxLayout(widget);
drawWidget = new DrawWidget(widget);
mainLayout->addWidget(drawWidget);
centralWidget()->setLayout(mainLayout);
}
And this is my main.cpp:
#include "mainwindow.h"
#include <QtWidgets/QApplication>
#include <QtPlugin>
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.resize(1000,600);
w.show();
return a.exec();
}
I build this project in release version.Any idea? Thank you!
I had the same problem few weeks ago in my case the problem was the additional library. Make sure that you got builds of the additional library debug for debug building and release for release building. Add AdditionalLibraryDebug/bin folder to the Path environment variable when you build Debug Version and AdditionalLibraryRelease/bin when you build Release version (not both in same time)
Good Luck :) i solved my problem on this way. :)
I found this very useful
http://www.itk.org/Wiki/VTK/FAQ#Shared_builds_of_VTK_and_debugging_QVTKWidget_using_Visual_Studio
It happens that libraries depend on the debug version of VTK so you have to build both release and debug and be sure to add the path in the debugging properties.
The problem is when run the application, appears a message to close the application without clarifying the cause of the problem.
the application is a simple calculator in order to addition two numbers.
This application contains six GUI objects.
Two QSpinBox to input the numbers.
Three Qlabel, two Qlabel to display +, = ,and one other to output the result of addition of two number, and this object is the reason of the problem.
Finally, one QPushButton to display the result in a Qlabel.
Now, It's time to display code:
I have three files(main.cpp, calculator.h, calculator.cpp).
-- Main.cpp --
#include "calculat.h"
int main(int argc, char *argv[]){
QApplication app(argc, argv);
Calculator calc;
calc.show();
return app.exec();
}
-- calculator.h --
#ifndef CALCULATOR_H
#define CALCULATOR_H
#include <QWidget>
class QSpinBox;
class QLabel;
class Calculator : public QWidget {
Q_OBJECT
public:
Calculator();
private slots:
void on_addNumber_clicked();
public:
QSpinBox *firstValueSpinBox;
QSpinBox *secondValueSpinBox;
QLabel *resultLabel;
};
#endif // CALCULATOR_H
-- calculator.cpp --
#include "calculator.h"
#include <QPushButton>
#include <QSpinBox>
#include <QLabel>
#include <QHBoxLayout>
Calculator::Calculator(){
QPushButton *addButton = new QPushButton("Add");
firstValueSpinBox = new QSpinBox();
secondValueSpinBox = new QSpinBox();
resultLabel = new QLabel();
QLabel *addLabel = new QLabel("+");
QLabel *equalLabel = new QLabel("=");
connect(addButton, SIGNAL(clicked()), this, SLOT(on_addNumber_clicked()));
QHBoxLayout *layout = new QHBoxLayout(this);
layout->addWidget(firstValueSpinBox);
layout->addWidget(addLabel);
layout->addWidget(secondValueSpinBox);
layout->addWidget(addButton);
layout->addWidget(equalLabel);
layout->addWidget(resultLabel);
}
void Calculator::on_addNumber_clicked(){
int num = this->firstValueSpinBox->value();
int num2 = this->secondValueSpinBox->value();
QString outResult = QString::number(num + num2);
resultLabel->setText(outResult); //<< the problem here
}
I doubt in this line:
resultLabel->setText(outResult);
When remove that previous line, the application work fine.
Conclusion, the problem in this Qlabel object that responsible for display the final result.
QLabel *resultLabel; // declaration in calculator.h
resultLabel->setText(outResult); // in calculator.cpp
There are no crashing bugs in your code. It runs just fine. Your problem is a rather classical result of stale object files that don't match the code anymore. The code generated from moc_calculator.cpp is stale. How are you building the project: manually, or using make/qmake? If you use make/qmake or make/cmake (say, from Qt Creator), do the following:
Completely remove the build directory (you'll find it one directory above the sources).
Rebuild.
There's a functional bug that doesn't result in a crash, simply in a misbehavior. Maybe it's even a typo. Instead of resultLabel->setText("outResult");, you want
resultLabel->setText(outResult);