Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Alles rund um die Programmierung mit Qt
Antworten
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Beitrag von Meho »

Hallo ihr Lieben,
ich brauch bitte noch einmal eure Hilfe, ich bin voll am verzweifeln.

Gestern Abend hat alles noch funktioniert, Heute backupe ich nur meine Projektordner (einfach eine Kopie im anderen Verzeichnis) und löschte den PROJEKTNAME-build-desktop-Qt_4_8_1_in_Pfad__System__Release, wie ich es schon oft getan hatte.

Ich bekomme nun beim kompilieren, ohne das ich etwas zu gestern Abend geändert hatte folgende Fehler:

Cannot open file for reading: No such file or directory
QWidget: Must construct a QApplication before a QPaintDevice
Das Programm ist abgestürzt.


Der erste Fehler wurde von mir programmiert und erscheint wenn es noch keine *.config Datei zu meinem Programm gibt, normalerweise sollte ich jetzt einen Dialog sehen wo ich die *.config erstelle.

Testweise habe ich Teile meines Quellcodes auskommentiert was mich noch mehr verzweifeln lies, denn meine main(); …. sieht jetzt so aus:

Code: Alles auswählen

// main.cpp
#include "main.h"

int main ( int argc, char *argv[] )
{
  QApplication app( argc, argv );

  return app.exec();
}
Alles andere ist auskommentiert, wie kann er denn da noch einen Fehler von mir ausgeben, dessen Objekt nie erzeugt wird?
Cannot open file for reading: No such file or directory

Ich habe schon nach dem Fehler gesucht und folgendes gefunden:
"Do as the error message suggests: construct a QApplication instance before creating any other widget.
If you really did that, then it’s most likely the you mix debug and release versions of your libraries."

Nur ich wüsste nicht wie ich das hätte mixen sollen?
Kann so was ausversehen passieren und wie mache ich es rückgängig?

Edit: Mir ist noch etwas eingefallen, da ich an einem anerem Problem hing und die Debugfunktion in QT Creator nicht richtig funktionierte hatte ich noch folgendes Paket installiert.:
qtcreator-dbg - debugging symbols for Qt Creator IDE
hat das was damit zu tun?

Bin wie immer um jede Hilfe dankbar!

Gruß Meho

Quelle:
http://qt-project.org/forums/viewthread/12838
Mr.Crank
Beiträge: 38
Registriert: 16. April 2013 15:21

Re: Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Beitrag von Mr.Crank »

Hey Meho ,

keine Sorge , ich hoffe du hast noch alle Original Files ;)

So macht man auch keine Sicherungskopie ^^ entscheidend sind deine dafür die internen Links, welche teilweise Ursprungs gebunden sind.
Lege ein neues Projekt, meinetwegen Kopie_130930 oder so an. (selbe Einstellungen und Einbindungen wie beim alten versteht sich)
Nun Kopiere nur alle Datein ( .h .cpp .src usw. bis auf .pro usw. nicht ) und binde sie richtig ein hinzufügen->headerdatei->bestehende usw.,
danach sollte es ganz normal wieder funzen ;)

Oder wenn du MSVS hast, versuch von Debugg in den Release Mode zu kompelieren.

Gruß Mr.Crank
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Beitrag von Meho »

Hi Mr.Crank,
danke für deine Antwort.

Ich habe es gerade ausprobiert und die bisherigen 3 Fehler wurden durch 148 neue ersetzt :-(
Alle sind sie von dieser Art:

Fehler:undefined reference to `QSqlDatabase::~QSqlDatabase()'
: In function `MainTable::addingTab()':


EDIT:
ach ich hab händisch die Zeile
QT += sql
in die *.pro Datei eingefügt und jetzt geht es -> NICHT :-(
Fehler wie im ersten Post ;-( heul

Wenn ich mir das Beispiel aus der Doku ansehe
http://qt-project.org/doc/qt-4.8/sql-cachedtable.html
wird zwar nichts von der QT += sql in der *.pro datei gesagt, aber sie stehn da auch drin.
ich kann übrigens auch kein
#include <QtSql> einbinden Fehler: "Es existiert keine Datei oder verzeichnis dieser Namens"
sondern nur:
#include <QtSql/QtSql>

Irgendwie ist in der Datenbanksache der Wurm drin :evil: , glaube ich :?:

Gibt es noch weitere Ideen ?
Ich hab 7 Dateien mit Header es ist denk ich ungünstig die alle zu posten ... vielelciht nur mal die Datenbankdatei?
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Beitrag von Meho »

Ich konnte den Fehler einengen nur leider versteh ich es nicht :-(
Ich habe mich daher entschlossen doch mal einige meiner Klassen zu posten und hoffe es findet sich ein hilfsbereiter Boardnutzer der sich das mal durchschaut.
________________________
Erklärung:

Ich nehme in meinem Programm Zugriff auf eine Datenbank um die Zugriffsinformationen (Host, User, Name, ..)zu laden und zu speicher (auf der HDD) nutze ich die Klasse "setingmanager" (das eine T fehlt mit absicht 8) ).
Der Fehler tritt NICHT auf, wenn ich in db connect (Klasse nimmt Zugriff auf Datenbank)
die Zeile

Code: Alles auswählen

 DbEinstellungen = ladeAusDB.loadSettingsFromFile();
auskommentiere, so wie es gerade der fall ist. Also wenn ich nicht die Daten von der Festplatte laden sonder per Hand in den Code eingebe.

bevor der Feheler:
QWidget: Must construct a QApplication before a QPaintDevice
auftritt gibt er mir noch ein cerr, was ich geschrieben habe, aus der Funktion .loadSettingsFromFile() (setingmanager ) aus.
________________________
Was ich nicht vertehe:

In meiner Main frage ich als erstes ab ob diese config Datei aus der ich die Datenbankeinstellungen lesen möchte
existiert

Code: Alles auswählen

 SetingManager lSettings;

  if (!lSettings.check())
  {
und wenn nicht lassse ich eine QMessageBox mit exec starten, sodass das Programm ja gar nicht bis an diese Stelle in dbconnect laufen sollte.
________________________
Was mir helfen könnte:

Wie strukturiere ich meine Klassen, dass ich erst feststelle ob eine *.conf Datei existiert und wenn nicht eine schreiben lasse.

Wenn ihr doch noch die anderen Klassen sehen wollt, gerne, ich möchte nur nichts unwesentliches posten.

Vielan Dank schonmal für eure Mühen!!
________________________
Der Code

main.h

Code: Alles auswählen

#ifndef MAIN_H
#define MAIN_H

#include "DbmsWindow.h"
#include "setingmanager.h"
#include <QApplication>
#include <iostream>
using namespace std;
class main
{
private:
public:
    main();
};
#endif // MAIN_H
main.cpp

Code: Alles auswählen

// main.cpp
#include "main.h"

int main ( int argc, char *argv[] )
{
  QApplication app( argc, argv );
    
  //Vor dem Start des Programm prüfen ob Einstellungen zur Datenbank geladen werden können
  SetingManager lSettings;


  if (!lSettings.check())
  {
      //wird benötigt um Umlaute richtig darzustellen
      wchar_t* QboxText = L"Die Datei \"d_manager.conf\" konnte nicht gefunden werden.\n"\
              "Diese enthällt die Grundeinstellungen für den Datenbankzugriff.\n"\
              "Wenn Sie dieses Programm das erste mal aufrufen muss diese erst neu erstellt werden.\n\n"\
              "Möchten Sie jetzt die Grundkonfigurationen festlegen?\n";

      QMessageBox abfrage;
      abfrage.setWindowTitle("Keine Konfiguration gefunden!");
      abfrage.setIcon(QMessageBox::Question);
      abfrage.setText(QString(QString::fromWCharArray(QboxText)));
      abfrage.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
      int usedButton = abfrage.exec();
       //used Butten enthält den genutzen Button
      db_setting datenbankEinstellungen;

      switch (usedButton) {
        case QMessageBox::Yes:

          // EinstellungsDialog erzeugen uns starten.
          //bewirkt, dass die Codeausführung solange angehalten wird bis der Dialog beendet wurde.
          // exec ist immer modal aber übergibt die Kontrolle nicht an da aufrufende Programm zurück,
          //imgegensatz zu .show();
          //daher "datenbankEinstellungen.setModal(true);" unnötig!
          datenbankEinstellungen.exec();

        break;
        case QMessageBox::No:
            return 0;

        }

   }

    DbmsWindow mw;
    mw.show();

  return app.exec();
}
setingmanager.h

Code: Alles auswählen

#ifndef SETINGMANAGER_H
#define SETINGMANAGER_H

#include "settings.h"
#include "db_setting.h"
#include <QMap>
#include <QColor>
#include <QFile>
#include <QDataStream>
#include <iostream>

using namespace std;


class SetingManager
{
public:
    SetingManager();
    Settings loadSettingsFromFile();
    bool writeNewSettingsToFile(Settings uebergebeneEinstellung);
    bool loadedCorrect;
    bool check();
private:
    Settings dieEinstellungen;
    QMap<QString, QString> map;

};

#endif // SETINGMANAGER_H
setingmanager.cpp

Code: Alles auswählen

#include "setingmanager.h"
#include <QMessageBox>

SetingManager::SetingManager()
{
    loadedCorrect=false;
}

Settings SetingManager::loadSettingsFromFile()
{
    quint32 n;

    // Einlesen der gespeicherten Grundeinstellung in eine Map
    QFile confDatei("d_manager.conf");
    if (!confDatei.open(QIODevice::ReadOnly))
    {
            cerr << "Cannot open file for reading:s "
             << qPrintable(confDatei.errorString()) << endl;

            //wird benötigt um Umlaute richtig darzustellen
            wchar_t* QboxText = L"Beim Laden ist ein Fehler aufgetreten \n\n"
                    "Mögliche Ursachen:\n"
                    "1. \"d_manager.conf\" konnte nicht gefunden werden. \n"
                    "2. \"d_manager.conf\" ist beschädigt. \n"
                    "3. \"d_manager.conf\" wurde noch nicht erstellt. \n"
                    "4. \"d_manager.conf\" kann nicht gelesen werden. \n";

            cout << "foobaaahhhh"<<endl;
            QMessageBox msgBox;
            msgBox.setWindowTitle("Laden fehlerhaft!");
            msgBox.setIcon(QMessageBox::Critical);
            msgBox.setText(QString(QString::fromWCharArray(QboxText)));
            msgBox.exec();


    }else{
            QDataStream in(&confDatei);
            in.setVersion(QDataStream::Qt_4_1);
            in >> n >> map;

            //Umwandeln der Map in eigenes Format
            dieEinstellungen.setHostName(map.value("Host"));
            dieEinstellungen.setDbName(map.value("dbName"));
            dieEinstellungen.setDbUserName(map.value("UserName"));
            dieEinstellungen.setDbUserPassword( map.value("UserPw"));
            dieEinstellungen.setLastUserName(map.value("lUser"));
            dieEinstellungen.setPort( map.value("Port"));

            loadedCorrect=true;
    }

    return dieEinstellungen;
}

bool SetingManager::writeNewSettingsToFile(Settings uebergebeneEinstellung)
{
    dieEinstellungen=uebergebeneEinstellung;
    bool richtigGeschrieben=false;

    map.insert("Host", dieEinstellungen.getHostName());
    map.insert("Port", dieEinstellungen.getDbPort());
    map.insert("dbName", dieEinstellungen.getDbName());
    map.insert("UserName",dieEinstellungen.getDbUserName());
    map.insert("UserPw", dieEinstellungen.getDbUserPassword());
    map.insert("lUser", dieEinstellungen.getLastUserName());

   /* QMessageBox msgBox2;
    msgBox2.setWindowTitle("Fukushima");
    msgBox2.setText(QString("PLOP;\n"
                           "Host: %1\n dbName: %2,\nUserName: %3,\nPW: %4,\nlU: %5").arg(einstellung.getHostName(),einstellung.getDbName(),einstellung.getDbUserName(),einstellung.getDbUserPassword(),einstellung.getLastUserName()));
    msgBox2.exec();

    QMessageBox msgBox;
    msgBox.setWindowTitle("NACH map VOR schreiben");
    msgBox.setText(QString("PLOP;\n"
                           "Host: %1\ndbName: %2,\nUserName: %3,\nPW: %4,\nlU: %5").arg(
                            map.value("Host"),map.value("dbName"),map.value("UserName"),
                            map.value("UserPw"),map.value("lUser") ));
    msgBox.exec();
    */
    QFile confDatei("d_manager.conf");
    if (!confDatei.open(QIODevice::WriteOnly))
    {
        cerr << "d_manager.conf konnte nicht geschrieben werden!"
             << qPrintable(confDatei.errorString())<<endl;

        //wird benötigt um Umlaute richtig darzustellen
        wchar_t* QboxText = L"Beim Speichern ist ein Fehler aufgetreten \n\n"
                "Haben Sie schreibrechte auf dem Datenträger? \n"
                "Bitte versuchen Sie es noch einmal!\n";

        QMessageBox msgBox;
        msgBox.setWindowTitle("Speichern fehlerhaft!");
        msgBox.setIcon(QMessageBox::Critical);
        msgBox.setText(QString(QString::fromWCharArray(QboxText)));
        msgBox.exec();
    }else
    {
        QDataStream out (&confDatei);
        out.setVersion(QDataStream::Qt_4_1);
        out<<quint32(0x12345678)<<map;
        richtigGeschrieben=true;
    }
    return richtigGeschrieben;
}

bool SetingManager::check()
{
    bool confAvailable=false;
    QFile confDatei("d_manager.conf");
    if (!confDatei.open(QIODevice::ReadOnly))
    {
        confAvailable=false;
    }else
    {
        confAvailable=true;
    }
    return confAvailable;
}
dbconnect.h

Code: Alles auswählen

#ifndef DBCONNECT_H
#define DBCONNECT_H

#include "setingmanager.h"
#include "settings.h"

//#include <QtSql/QSqlDatabase>
//#include <QtSql/QSqlQuery>
//#include <QtSql/QSqlQueryModel>
#include <QtSql/QtSql>

#include <QMessageBox>



class DbConnect
{
public:
    DbConnect();
    void auslesen(QString query, QSqlQueryModel *model);
    bool wasDbwritten();
    bool writeNewTables();
    bool writeNewExample();
    bool repairDatabase();
    bool connectionOK;

private:
    QSqlDatabase db;
    //QSqlQuery qry;

};

#endif // DBCONNECT_H

dbconnect.cpp

Code: Alles auswählen

#include "dbconnect.h"
#include <QtSql/QSqlError>

DbConnect::DbConnect()
{
    SetingManager ladeAusDB = SetingManager();
    Settings DbEinstellungen = Settings();

    /*DbEinstellungen = ladeAusDB.loadSettingsFromFile();
                      db = QSqlDatabase::addDatabase("QMYSQL","DDatabase");
                      db.setHostName(DbEinstellungen.getHostName());
                      db.setDatabaseName(DbEinstellungen.getDbName());
                      db.setUserName(DbEinstellungen.getDbUserName());
                      db.setPassword(DbEinstellungen.getDbUserPassword());
                      db.setPort(DbEinstellungen.getDbPort().toInt());
                      connectionOK = db.open();
     */



                          db = QSqlDatabase::addDatabase("QMYSQL","DDatabase");
                          db.setHostName("localhost");
                          db.setDatabaseName("test");
                          db.setUserName("test");
                          db.setPassword("test");
                          db.setPort(3301);
                          connectionOK = db.open();


    if (!connectionOK){
    QMessageBox msgBox;
    msgBox.setWindowTitle("Datenbankfehler");
    msgBox.setText(QString("ACHTUNG;\n"
    "Es konte keine Verbindung zur Datenbank hergestelt werden!\n\n"
    "Fehler: %1 \n"
    "Setzen Sie Die Einstllungen unter \"Einstellungen\" -> \"Datenbankeinstellungen setzen\" neu!").arg(connectionOK));
    msgBox.exec();
    }



}

void DbConnect::auslesen(QString query, QSqlQueryModel *model){

     model->setQuery(query,db);



}
bool DbConnect::wasDbwritten() //prüft ob die Datenbank alle nötigen Tabellen enthällt
{
    bool readed=false;
   if (!db.tables().contains("dm_view") ||
        !db.tables().contains("dm_userview") ||
        !db.tables().contains("dm_firma") ||
        !db.tables().contains("dm_user") ||
        !db.tables().contains("dm_person") ||
        !db.tables().contains("dm_kunden") ||
        !db.tables().contains("dm_projektuser") ||
        !db.tables().contains("dm_projektperson") ||
        !db.tables().contains("dm_anschperson") ||
        !db.tables().contains("dm_rollen") ||
        !db.tables().contains("dm_phone") ||
        !db.tables().contains("dm_email") ||
        !db.tables().contains("dm_projekt") ||
        !db.tables().contains("dm_anschrift")
       )
    {
        readed=true;
    }
    return readed;
}
bool DbConnect::writeNewTables()    //löscht alle Tabellen und schreibt sie neu
{
    QSqlQuery qry(QSqlDatabase::database( "DDatabase" ));
    bool erstellenErfolgreich;
     if (connectionOK){

          qry.prepare( "DROP TABLE IF EXISTS dm_anschrift");
          qry.exec();
          qry.prepare( "CREATE TABLE dm_anschrift(anschriftid INTEGER UNIQUE AUTO_INCREMENT PRIMARY KEY,     Strasse VARCHAR(30) NOT NULL, Hausnummer VARCHAR(5) NOT NULL, PLZ INTEGER(5) NOT NULL, Ort VARCHAR(30) NOT NULL)" );
          qry.exec();
                 // hier steht eigentlich noch mehr nur gekürzt da es das gleiche ist       


          erstellenErfolgreich=true;

    }
    return erstellenErfolgreich;
}

bool DbConnect::repairDatabase()    // schreibt alle fehlenden Tabellen in die Datenbank
{
    bool foo=false;
    QSqlQuery qry(QSqlDatabase::database( "DDatabase" ));

    if (connectionOK){


       qry.prepare( "CREATE TABLE IF NOT EXISTS dm_anschrift(anschriftid INTEGER UNIQUE AUTO_INCREMENT PRIMARY KEY, Strasse VARCHAR(30) NOT NULL, Hausnummer VARCHAR(5) NOT NULL, PLZ INTEGER(5) NOT NULL, Ort VARCHAR(30) NOT NULL)" );
       qry.exec();


        // hier steht eigentlich noch mehr nur gekürzt da es das gleiche ist           

       foo=true;
    }
    return foo;
}

bool DbConnect::writeNewExample()   //schreibt Beispieldaten in die Datenbank
{
    QSqlQuery qry(QSqlDatabase::database( "DDatabase" ));
    bool foo=false;

    if (connectionOK)
    {

        qry.prepare( "INSERT INTO dm_person (Vorname, Nachname, Anrede ) VALUES ('John', 'Doe','Herr')" );
        qry.exec();
       // hier steht eigentlich noch mehr nur gekürzt da es das selbe ist

        foo=true;
    }
    return foo;
}

Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Funktion wird ausgeführt ohne Aufruf, vermischte Libs??

Beitrag von Meho »

Soo,
es funktioniert wieder :-) *freu*

anscheinend lag es daran, dass Qt die Bibliotheken die ich importiert hatte falsch gelinkt hat. Dies könnte daran gelegen haben, dass ich versehentlich zwischen releas und debugmode gewechselt hatte oder mal nachts meinen pc nicht richtig aus gemacht hatte. :oops:

Vielen Dank hier nochmal an Mr.Crank der mir sehr geholfen hatte!

Gruß Meho
Antworten