QT c++ multiple definition and first defined here error - c++

I added a part in the main.cpp file that asks for a password before the window opens. It gets what it needs from the help.h and cnstnt.h files. Then I created a dialog named settings and tried to change the password here. It was working fine in my previous test project, but when I used the same things in this project, I encountered a first defined here error. I checked, I did run qmake and rebuild but nothing changed. How can I fix this problem? I'm new to C++ and QT.
here is my codes
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include <QMessageBox>
#include "cnstnt.h"
#include "help.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setStyle("fusion");
a.setQuitOnLastWindowClosed(false);
MainWindow w;
QString login = QInputDialog::getText(NULL, "Login","username",QLineEdit::Normal);
if (login == cnstnt::username)
{
QString getPassword = QInputDialog::getText(NULL, "Login","password",QLineEdit::Password);
QString hashpassword = hlpr::hashPassword(getPassword.toUtf8());
if(hashpassword == hlpr::getTxtPassword()){
w.show();
}else{
QMessageBox::warning(nullptr, "error!", "wrong password!");
}
}
else
{
QMessageBox::warning(nullptr, "error!", "wrong username!");
}
return a.exec();
}
cnstnt.h
#ifndef CNSTNT_H
#define CNSTNT_H
#include <QtWidgets>
namespace cnstnt {
QString TEXT_DIR = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/test/password.txt";
QString username = "admin";
}
#endif // CNSTNT_H
help.h
#ifndef HELP_H
#define HELP_H
#include <QCryptographicHash>
#include "cnstnt.h"
namespace hlpr {
// login actions
QString hashPassword(QByteArray str){
QByteArray step1 = QCryptographicHash::hash((str),QCryptographicHash::Md5).toHex();
QString lastHash = QString(QCryptographicHash::hash((step1),QCryptographicHash::Sha512).toHex());
return lastHash;
}
QString getTxtPassword(){
QString currentPassword;
QFile file(cnstnt::TEXT_DIR);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)){
QTextStream in(&file);
currentPassword = in.readLine();
file.close();
}
return currentPassword;
}
bool setTxtPassword(QString newPass){
QFile file(cnstnt::TEXT_DIR);
if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
QTextStream stream(&file);
QByteArray newPassType = newPass.toUtf8();
stream << hashPassword(newPassType);
file.close();
return true;
}
return false;
}
}
#endif // HELP_H
settingdialog.h
#ifndef SETTINGDIALOG_H
#define SETTINGDIALOG_H
#include <QDialog>
#include <QMessageBox>
#include "help.h"
namespace Ui {
class settingDialog;
}
class settingDialog : public QDialog
{
Q_OBJECT
public:
explicit settingDialog(QWidget *parent = nullptr);
~settingDialog();
private slots:
void on_pushButton_8_clicked();
private:
Ui::settingDialog *ui;
};
#endif // SETTINGDIALOG_H
settingdialog.cpp
#include "settingdialog.h"
#include "ui_settingdialog.h"
settingDialog::settingDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::settingDialog)
{
ui->setupUi(this);
}
settingDialog::~settingDialog()
{
delete ui;
}
void settingDialog::on_pushButton_8_clicked()
{
QString TEXT_DIR = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/test/password.txt";
QString savedPassword = hlpr::getTxtPassword();
QString curPassword = ui->oldPassBox->text();
QString newPass = ui->newPassBox->text();
QString confirmPass = ui->confirmPass->text();
QByteArray curHash = curPassword.toUtf8();
if(newPass != confirmPass) {
QMessageBox::information(this, "Bilgi", "Yeni şifreniz ile tekrarı eşleşmiyor!");
}else if(newPass == curPassword){
QMessageBox::information(this, "Bilgi", "Mevcut şifreniz ile yeni şifreniz ile aynı olamaz!");
}else if(savedPassword != hlpr::hashPassword(curHash)) {
QMessageBox::information(this, "Bilgi", "Mevcut şifreniz hatalı!");
}else{
bool status = hlpr::setTxtPassword(newPass);
if(status){
ui->oldPassBox->clear();
ui->newPassBox->clear();
ui->confirmPass->clear();
QMessageBox::information(this, "Başarılı", "Şifreniz başarıyla güncellendi.");
}else{
QMessageBox::warning(this, "Hata!", "Şifreniz güncellenirken hata oluştu!");
}
}
}
errors
X:\DataLoggerQT\QtSerialMonitor-master\src\help.h:11: error:
multiple definition of hlpr::passwordHash(QByteArray)' debug/mainwindow.o: In function ZSt19__iterator_categoryIPK7QStringENSt15iterator_traitsIT_E17iterator_categoryERKS4_':
X:\DataLoggerQT\QtSerialMonitor-master\build-QtSerialMonitor-Desktop_Qt_5_15_2_MinGW_32_bit-Debug/../src/help.h:11:
multiple definition of `hlpr::passwordHash(QByteArray)'
X:\DataLoggerQT\QtSerialMonitor-master\src\help.h:11: first defined
here
X:\DataLoggerQT\QtSerialMonitor-master\src\help.h:28: error: multiple definition of hlpr::setTxtPassword(QString)' debug/moc_mainwindow.o: In function ZN4hlpr14setTxtPasswordE7QString':
X:\DataLoggerQT\QtSerialMonitor-master\build-QtSerialMonitor-Desktop_Qt_5_15_2_MinGW_32_bit-Debug/debug/../../src/help.h:28: multiple definition of `hlpr::setTxtPassword(QString)'

You have included helper.h in two header files - settingdialog.h and main.cpp, mainwindow.h is included in main.cpp and, I suppose, includes settingdialog.h itself. Or, maybe, it's included through any other included header. So you've got multiple definition error, one per include.
To avoid such kind of errors, functions in helper.h file should be declared with extern keyword and their implementation should be moved to helper.cpp file. It would prevent you from any potential problems in future. And you should always declare functions in this way.
And at last, you do not need to include helper.h in settingdialog.h as you use it's functions in cpp. Move include to settingdialog.cpp. Keep it in mind to include files only there, where they are really used, it would minimize compilation time.

Related

_popen() returns nothing

This is a Qt program. I am trying to run gcc command and get the result using _popen(on Windows). However, I get no output.
After debugging, I find that gcc command runs ok.
void editor::on_action_Compile_triggered()
{
QString str = "gcc \""+curFile+"\" -o \""+outputFile+"\" 2>&1"; //compile curFile
FILE *fp = _popen(str.toStdString().data(),"r");
if (!fp)
{
ui->Log->setText("Error."); //Log is a text browser
}
else
{
QString tmpStr = "";
char tmp[1024] = { 0 };
while (fgets(tmp, 1024, fp) != NULL) //read fp
tmpStr += (QString)tmp;
ui->Log->setText(tmpStr); //print to screen
}
_pclose(fp);
}
According to me, you are not having a problem. Your above code is working for me (as long as I declare a correct curfile and outputFile). You are not having an ouput because gcc has successfully compiled the file. You may want to verify if the file called outputFile has been produced. Indeed, when gcc succeeds, it does not ouput anything.
Otherwise, you might be having a problem with your signal/slot connexion which does not trigger the slot on_action_Compile_triggered(then please read on the complete code provided below)
To test it try to modify your curFile to point to an inexisting file and you will get an ouput error typical of gcc.
To check this, as for me, I created a QmainWindow with a QPushButton button (called pushbutton) and a QtextEdit (called Log). I provide my complete code below.
When I have an error (for instance the compiled file is not found. to emulate this, rename your curFile into a wrong file), I obtain this (using your code above).
When I do not have any error, I obtain nothing in the QTextEditcontrol but the outputFile executable file is produced by gcc in the directory:
Here is my code:
// QMainWindow.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();
public slots:
void compile();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
// QMainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::compile);
}
MainWindow::~MainWindow()
{
QObject::disconnect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::compile);
delete ui;
}
void MainWindow::compile()
{
QString curFile("..\\..\\T0180694\\test.c");
QString outputFile("..\\..\\T0180694\\test.exe");
//copied all from your code
QString str = "gcc \""+curFile+"\" -o \""+outputFile+"\" 2>&1"; //compile curFile
FILE *fp = _popen(str.toStdString().data(),"r");
if (!fp)
{
ui->Log->setText("Error."); //Log is a text browser
}
else
{
QString tmpStr = "";
char tmp[1024] = { 0 };
while (fgets(tmp, 1024, fp) != NULL) //read fp
tmpStr += (QString)tmp;
ui->Log->setText(tmpStr); //print to screen
}
_pclose(fp);
//until here
}
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}

How to get file name in Qt?

I have modified the Text Finder example which I got from a Qt Tutorial and made a Text Viewer. In this program, the user types in the address of the file and clicks the Search button. The program then displays the content of the text file. Below is my code.
text_finder.cpp:
#include "text_finder.h"
#include "ui_text_finder.h"
#include <QHBoxLayout>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
Text_Finder::Text_Finder(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Text_Finder)
{
ui->setupUi(this);
}
Text_Finder::~Text_Finder()
{
delete ui;
}
void Text_Finder::loadFile(QFile file){ // I have to pass the file name as parameter.
QFile inputFile(file);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString line = in.readAll();
inputFile.close();
ui->read->setText(line);
QTextCursor cursor = ui->read->textCursor();
cursor.movePosition(QTextCursor::Start, QTextCursor::MoveAnchor, 1);
}
void Text_Finder::on_search_clicked()
{
// Code that gets the path from the text box.
loadFile();//Parameters not passed yet.
}
I have not yet entered the code which gets the name of the file from the address of the text box. I will have to pass the file to the loadFile() function which will enter the contents into the Text Edit in the center of the program. I want a solution to get the name of the file of which the user enters. For example, the user might enter, "/home/user/input.txt". The program should get the contents of that file and forward it to loadFile(). An solution with an explanation on how the various parts work is needed. I am using Qt Creator on Ubuntu 15.04 (Beta).
If i understand you correctly, the user types the full path or address of the file in the text box and you want to get just the name of the file out of the full path the user entered.
EDIT: I realized using 'QFileDialog' was the ideal way to get the file name. So this
is how i redesigned the whole code;
text_finder.h
#ifndef TEXT_FINDER_H
#define TEXT_FINDER_H
#include <QDialog>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>
#include <QFileDialog>
class Text_Finder : public QWidget{
Q_OBJECT
public:
Text_Finder(QWidget *parent = 0);
~Text_Finder();
public slots:
void on_search_clicked();
void open();
//void loadFile(QString const &filename);
private:
void loadFile(QString const &filename);
QLineEdit *txtFileName;
QTextEdit *txtFileContents;
QString fileName;
QPushButton *search;
QPushButton *openFile;
};
#endif
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
text_finder.cpp
#include "text_finder.h"
Text_Finder::Text_Finder(QWidget *parent) : QWidget(parent) {
openFile = new QPushButton("Open File");
connect(openFile, SIGNAL(clicked()), this, SLOT(open()));
txtFileName = new QLineEdit;
search = new QPushButton("&Search");
txtFileContents = new QTextEdit;
QHBoxLayout *dialogAndViewLayout = new QHBoxLayout;
dialogAndViewLayout->addWidget(openFile);
dialogAndViewLayout->addWidget(txtFileName);
dialogAndViewLayout->addStretch();
dialogAndViewLayout->addWidget(search);
QVBoxLayout *layout = new QVBoxLayout;
layout->addLayout(dialogAndViewLayout);
layout->addWidget(txtFileContents);
connect(search, SIGNAL(clicked()), this, SLOT(on_search_clicked()));
setLayout(layout);
}
Text_Finder::~Text_Finder(){
delete txtFileName;
delete txtFileContents;
delete search;
delete openFile;
}
void Text_Finder::loadFile(QString const &filename){
QFile inputFile(filename);
inputFile.open(QIODevice::ReadWrite | QIODevice::Text);
QTextStream textStream(&inputFile);
QString contents = textStream.readAll();
inputFile.close();
txtFileContents->setPlainText(contents);
}
void Text_Finder::on_search_clicked() {
loadFile(fileName);
}
/*this slot opens a file dialog. After the file has been selected, it sets
the file to the text text edit box*/
void Text_Finder::open() {
fileName = QFileDialog::getOpenFileName(this, "Open text", "/home/",
"");
txtFileName->setText(fileName);
}
mainwindow.cpp
#include "mainwindow.h"
#include "text_finder.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
Text_Finder *textFinder = new Text_Finder;
setCentralWidget(textFinder);
}
MainWindow::~MainWindow() {
}
Finally
main.cpp
#include "text_finder.h"
#include <QApplication>
int main(int argc, char **argv){
QApplication app(argc, argv);
Text_Finder *window = new Text_Finder;
window->show();
return app.exec();
}
Unless you're going to do some programmatic editing, you do not need to use QTextCursor at all.
I suggest you have a browse through the reference manual before trying to carry on since it's clear that you are not familiar with the bare-basics of the graphical widgets you're using.
If you're only reading in a file name and then displaying the contents in plain text format, this is all you need to do. (I'm assuming your filename is entered into a QLineEdit widget and ui->read is a QTextEdit widget)
void Text_Finder::loadFile(QString const &filename){ // I have to pass the file name as parameter.
QFile inputFile(filename);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString contents = in.readAll();
inputFile.close();
ui->read->setPlainText(contents);
}
void Text_Finder::on_search_clicked()
{
QString filename = ui->filename->text();
loadFile(filename);
}
EDIT:
I've created a fully-functional remake of your code, incorporating the changes I suggested. I have compiled and tested it and it is working as per your description.
Note: In the absence of your UI file, I've created the user interface manually.
text_finder.h
#ifndef TEXT_FINDER_H
#define TEXT_FINDER_H
#include <QMainWindow>
class QLineEdit;
class QTextEdit;
class Text_Finder : public QMainWindow{
Q_OBJECT
public:
Text_Finder(QWidget *parent = 0);
~Text_Finder();
public slots:
void on_search_clicked();
private:
void loadFile(QString const &filename);
QLineEdit *txtFileName;
QTextEdit *txtFileContents;
};
#endif // TEXT_FINDER_H
main.cpp
#include "text_finder.h"
#include <QApplication>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QPushButton>
#include <QLineEdit>
#include <QTextEdit>
#include <QFile>
#include <QTextStream>
Text_Finder::Text_Finder(QWidget *parent) :
QMainWindow(parent)
{
QWidget *ui = new QWidget(this);
QHBoxLayout *hLayout = new QHBoxLayout;
txtFileName = new QLineEdit(this);
QPushButton *loadButton = new QPushButton("Load File", this);
connect(loadButton, &QPushButton::clicked, this, &Text_Finder::on_search_clicked);
hLayout->addWidget(txtFileName);
hLayout->addWidget(loadButton);
QVBoxLayout *vLayout = new QVBoxLayout(this);
vLayout->addLayout(hLayout);
txtFileContents = new QTextEdit(this);
vLayout->addWidget(txtFileContents);
ui->setLayout(vLayout);
setCentralWidget(ui);
}
Text_Finder::~Text_Finder(){
// It's not necessary to explicitly delete any widgets.
// QObject implements the Composite Pattern, which takes care of all this automatically
}
void Text_Finder::loadFile(QString const &filename){
QFile inputFile(filename);
inputFile.open(QIODevice::ReadOnly);
QTextStream in(&inputFile);
QString contents = in.readAll();
inputFile.close();
txtFileContents->setPlainText(contents);
}
void Text_Finder::on_search_clicked()
{
QString filename = txtFileName->text();
loadFile(filename);
}
int main(int argc, char **argv){
QApplication app(argc, argv);
Text_Finder w;
w.show();
return app.exec();
}
HINT for future questions: You will get better answers quicker if you include an SSCCE in your question. What I've included in this edit is a suitable example.

undefined reference to vtable for DownloadManager

I am trying to integrate the working code into my program, but I receive the error displayed on the title while compiling. Here is the code:
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
****************************************************************************/
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QSslError>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <stdio.h>
QT_BEGIN_NAMESPACE
class QSslError;
QT_END_NAMESPACE
QT_USE_NAMESPACE
class DownloadManager: public QObject
{
Q_OBJECT
QNetworkAccessManager manager;
QList<QNetworkReply *> currentDownloads;
public:
DownloadManager();
~DownloadManager() = 0;
void doDownload(const QUrl &url);
QString saveFileName(const QUrl &url);
bool saveToDisk(const QString &filename, QIODevice *data);
public slots:
void execute();
void downloadFinished(QNetworkReply *reply);
void sslErrors(const QList<QSslError> &errors);
};
DownloadManager::DownloadManager()
{
connect(&manager, SIGNAL(finished(QNetworkReply*)),
SLOT(downloadFinished(QNetworkReply*)));
}
DownloadManager::~DownloadManager()
{}
void DownloadManager::doDownload(const QUrl &url)
{
QNetworkRequest request(url);
QNetworkReply *reply = manager.get(request);
#ifndef QT_NO_SSL
connect(reply, SIGNAL(sslErrors(QList<QSslError>)), SLOT(sslErrors(QList<QSslError>)));
#endif
currentDownloads.append(reply);
}
QString DownloadManager::saveFileName(const QUrl &url)
{
QString path = url.path();
QString basename = QFileInfo(path).fileName();
if (basename.isEmpty())
basename = "download";
if (QFile::exists(basename)) {
// already exists, don't overwrite
int i = 0;
basename += '.';
while (QFile::exists(basename + QString::number(i)))
++i;
basename += QString::number(i);
}
return basename;
}
bool DownloadManager::saveToDisk(const QString &filename, QIODevice *data)
{
QFile file(filename);
if (!file.open(QIODevice::WriteOnly)) {
fprintf(stderr, "Could not open %s for writing: %s\n",
qPrintable(filename),
qPrintable(file.errorString()));
return false;
}
file.write(data->readAll());
file.close();
return true;
}
void DownloadManager::execute()
{
QStringList args = QCoreApplication::instance()->arguments();
args.takeFirst(); // skip the first argument, which is the program's name
if (args.isEmpty()) {
printf("Qt Download example - downloads all URLs in parallel\n"
"Usage: download url1 [url2... urlN]\n"
"\n"
"Downloads the URLs passed in the command-line to the local directory\n"
"If the target file already exists, a .0, .1, .2, etc. is appended to\n"
"differentiate.\n");
QCoreApplication::instance()->quit();
return;
}
foreach (QString arg, args) {
QUrl url = QUrl::fromEncoded(arg.toLocal8Bit());
doDownload(url);
}
}
void DownloadManager::sslErrors(const QList<QSslError> &sslErrors)
{
#ifndef QT_NO_SSL
foreach (const QSslError &error, sslErrors)
fprintf(stderr, "SSL error: %s\n", qPrintable(error.errorString()));
#else
Q_UNUSED(sslErrors);
#endif
}
void DownloadManager::downloadFinished(QNetworkReply *reply)
{
QUrl url = reply->url();
if (reply->error()) {
fprintf(stderr, "Download of %s failed: %s\n",
url.toEncoded().constData(),
qPrintable(reply->errorString()));
} else {
QString filename = saveFileName(url);
if (saveToDisk(filename, reply))
printf("Download of %s succeeded (saved to %s)\n",
url.toEncoded().constData(), qPrintable(filename));
}
currentDownloads.removeAll(reply);
reply->deleteLater();
if (currentDownloads.isEmpty())
// all downloads finished
QCoreApplication::instance()->quit();
}
//int main(int argc, char **argv)
//{
// QCoreApplication app(argc, argv);
// DownloadManager manager;
// QTimer::singleShot(0, &manager, SLOT(execute()));
// app.exec();
//}
//#include "main.moc"
In the code above, I removed main() (i will just use the class) and include "main.moc" (this gives a not found error). I also added destructor just in case.
And here is the project file in QtCreator:
QT += widgets core network
CONFIG += console
CONFIG -= app_bundle
SOURCES = main.cpp \
gos.cpp \
download.cpp
HEADERS = gos.h
QMAKE_PROJECT_NAME = GoS
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/tutorials/addressbook/part7
INSTALLS += target
simulator: warning(This example might not fully work on Simulator platform)
What am I missing?
Is the code in a header file (.h) or in a source file (.cpp)? When subclassing from QObject, moc depends on the class definition being in a header.
So split the class definition from download.cpp into download.h and add it to the HEADERS variable. Remember to make distclean and then call qmake again to get a clean build.
Since the main.cpp file contains Q_OBJECT macro, you'll need to generate main.moc file and #include "main.moc" it at the end of the source file.
Actually, qmake should handle this itself, but you need to re-run qmake for your project after adding the new #include line and then re-build.

Use UI array in a function Qt C++

In my Windows forms code, ui is used to define graphical element by default. But I want to modify them in a function, like this:
The problems is that the debug tool tells me that ui is not declared in this scope.
#include <QMessageBox>
#include <QFile>
#include <QTextStream>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "datawindow.h"
void getData(ui){
QFile inputFile("C:\\pepoles.txt");
if (inputFile.open(QIODevice::ReadOnly)){
QTextStream in(&inputFile);
while ( !in.atEnd() ){
QString line = in.readLine();
ui->listWidgetData->addItem(line);
}
}
else{
QMessageBox::critical(this, "Erreur", "Une erreur s'est produite :(");
}
inputFile.close();
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
getData(ui);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actionNouvellesDonnees_triggered() {
w.show();
}
void getData(ui){
That line starts definition of getData function, which takes one variable, with type ui and no name (so it can't be accessed in the function code).
Add type...
void getData(MainWindow::Ui *ui){
Make getData() a member of MainWindow:
void MainWindow::getData()
{
QFile inputFile("C:\\pepoles.txt");
if (inputFile.open(QIODevice::ReadOnly)) {
QTextStream in(&inputFile);
while ( !in.atEnd() ) {
QString line = in.readLine();
ui->listWidgetData->addItem(line);
}
} else {
QMessageBox::critical(this, "Erreur", "Une erreur s'est produite :(");
}
inputFile.close();
}
Then, in your constructor:
ui->setupUi(this);
getData();
I recommend this approach since ui contains private members, so it's best to have a member function modify it.
Don't forget to declare getData() in the header file of your MainWindow class. You should probably make it private.
And btw, ui is not an array. It's an object pointer.

What is the cause of a segmentation fault error (signal name: SIGSEGV), and how would I find/fix it?

I have been working on a Qt Creator application, and just recently ran into a run-time error that I have no idea how to find and fix. The program just unexpectedly finishes once it starts up, and when I run the debug, it gives me the error:
The inferior stopped because it
received a signal from the operating
system.
Signal name: SIGSEGV
Signal meaning: Segmentation fault
Now I understand that this error is caused by attempted access to an invalid memory location, but I have absolutely no clue what I did to trigger it. The debugger seems to be pointing me to a specific line of code:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QString>
#include "ui_mainwindow.h"
#include "foamdata.h"
#include "domaingeneration.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
int getXDim() const { return ui->xDim->value(); } // THIS is where it points to!!
int getYDim() const { return ui->yDim->value(); }
private slots:
void on_findDir_clicked();
void on_create_clicked();
void on_generateDomain_clicked();
private:
Ui::MainWindow *ui;
DomainGeneration dg; //declaring second window as a member of main window
};
#endif // MAINWINDOW_H
That function is used in this:
#include "domaingeneration.h"
#include "ui_domaingeneration.h"
#include <QCheckBox>
#include "mainwindow.h"
DomainGeneration::DomainGeneration(QWidget *parent) :
QDialog(parent),
ui(new Ui::DomainGeneration)
{
ui->setupUi(this);
// Generating checkboxes for domain generation
MainWindow* main;
int x_dim = main->getXDim();
int y_dim = main->getYDim();
QVector<QCheckBox*> checkBoxVector;
for(int i = 0; i < x_dim; ++i){
for(int j = 0; j < y_dim; ++j){
checkBoxVector.append(new QCheckBox(this));
checkBoxVector.last()->setGeometry(i * 20, j * 20, 20, 20);
}
}
}
DomainGeneration::~DomainGeneration()
{
delete ui;
}
Here is the mainwindow source code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "functions.h"
#include "main.cpp"
#include <QtGui/QApplication>
#include <QFileDialog>
#include <fstream>
#include "foamdata.h"
#include "domaingeneration.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// This is the function that handles the directory search when the 'browse' button is pressed
void MainWindow::on_findDir_clicked()
{
QString path; //declaring the path to the base directory
path = QFileDialog::getExistingDirectory( //gathering the directory from QFileDialog class
this, tr("Choose the project directory"),
"/home",
QFileDialog::ShowDirsOnly
| QFileDialog::DontResolveSymlinks );
ui->baseDir->setText( path ); //setting the retrieved path into the line edit box
}
// This function makes the project by creating a new directory with name 'project_name'
// in the base directory, and collects the OpenFOAM version number and simulation type
void MainWindow::on_create_clicked()
{
QString project_name, foam_version, full_dir, slash, base_dir;
base_dir = ui->baseDir->text();
project_name = ui->projectName->text(); //getting the text from the 'projectName' field
foam_version = ui->version->currentText(); //getting the selection from the 'version' drop-down box
project_info.save_version(foam_version); //saving data in a global project variable
project_info.save_projName(project_name);
project_info.save_simType(ui->simType->currentText());
//first checking if the fields have input in them:
QString blank = "";
QString no_text0 = "Please enter project name";
if( project_name==no_text0 || (project_name==blank) ) {
ui->projectName->setText( no_text0 );
return;
}
QString no_text1 = "Please enter a valid directory";
if( base_dir==no_text1 || base_dir==blank || !QDir( base_dir ).exists() ) {
ui->baseDir->setText( no_text1 );
return;
}
slash = "/"; // needed to separate folders in the directory (can't use a literal)
full_dir = base_dir.append(slash.append(project_name));
project_info.save_directory(full_dir);
if( !QDir(full_dir).exists() ) //check if directory already exists
QDir().mkdir(full_dir); //creating directory
QString blockmesh_filename, suffix;
suffix = "_blockMeshDict";
slash = "/"; //must re-define
blockmesh_filename = full_dir.append( slash.append( project_name.append(suffix) ) );
std::ofstream create_file( blockmesh_filename.toStdString().c_str() ); //creating empty blockmesh file
}
void MainWindow::on_generateDomain_clicked() //opening the new window for domain generation
{
dg.show();
}
Can anybody help me find what the heck is going on?
The obvious is that you're not initializing MainWindow * main;:
MainWindow* main; // right here
int x_dim = main->getXDim();
int y_dim = main->getYDim();
There might, however, be other uninitialized values, the piece of code presented doesn't really say much.
Or here:
// Generating checkboxes for domain generation
MainWindow* main;
int x_dim = main->getXDim();
int y_dim = main->getYDim();
main definitely doesn't point anywhere!
You have a private data member ui in class MainWindow that is NULL. That variable is never set. In fact, there is no no way to set it. (Where is the setter?)