Table View zeigt nichts an ....



  • Qt stellt mich vor das nächste Problem ....

    Ich hab mein UI mit QtCreator erstellt, eine Stacked Widget, welches auf Seite 4 ein tableview enthält. Nun möchte ich per Knopfdruck eine Liste des Personals ausgeben.

    QSqlDatabase db = QSqlDatabase::database();
        db.open();
        QSqlTableModel tableModel;
        tableModel.setTable("users");
        tableModel.select();
        tableModel.removeColumn(0);
        ui->personallistview->setModel(&tableModel);
        ui->personallistview->show();
        ui->stackedWidget->setCurrentIndex(3);
    

    Wenn ich nun den Button "Personalliste" betätige, wird mir nur ein leeres Table View angezeigt. Links Oben in der Ecke ist ein anklickbares Viereck, was mich zu der annahme führt, das das TableView das Tablemodel akzeptiert hat ... aber leider keine Daten anzeigt. Die Datenbank ist richtig eingebunden (hab ich mit einem Testquery versucht), die Tabelle "users" ist vorhanden.

    Hat jemand bitte einen Tipp für mich?

    mal wieder,

    der Nala


  • Mod

    Das Model was du da erzeugst ist lokal auf dem Stack der Methode. Nach dem diese verlassen wird, wird auch dein Model zerstört.



  • Vielen Dank ... kurz umgeschrieben und funktioniert 1a ! 😃



  • Ich hab zu dem Thema nochmal ne Frage.
    Ich hab das tableView nun in einen Dialog ausgelagert und als editStrategie onfieldChange mitgegeben.

    Wenn ich nun allerdings einen Wert veränder erhalte ich folgende Meldung:

    QSqlQuery::value: not positioned on a valid record

    Der Code dazu:

    #include <QtSql>
    #include "personalliste.h"
    #include "ui_personalliste.h"
    #include "storage.h"
    
    personalListe::personalListe(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::personalListe),
        db(new QSqlDatabase),
        tableModel(new QSqlTableModel)
    {
        ui->setupUi(this);
        Storage lager;    
        db->open();    
        tableModel->setTable("users");
        tableModel->select();
        switch (lager.getLevel()){
        case 10:
            tableModel->removeColumns(0,2);
            tableModel->removeColumn(3);
            tableModel->removeColumn(5);
            tableModel->removeColumns(5,8);
        case 99:
            tableModel->removeColumn(0);
        }
        tableModel->setEditStrategy(QSqlTableModel::OnFieldChange);
        ui->tableView->setModel(tableModel);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->show();
    }
    
    personalListe::~personalListe()
    {
        delete ui;
        delete tableModel;
        delete db;
    }
    
    #ifndef PERSONALLISTE_H
    #define PERSONALLISTE_H
    
    #include <QDialog>
    #include <QtSql>
    
    namespace Ui {
        class personalListe;
    }
    
    class personalListe : public QDialog
    {
        Q_OBJECT
    
    public:
        explicit personalListe(QWidget *parent = 0);
        ~personalListe();
    
    private:
        Ui::personalListe *ui;    
        QSqlDatabase *db;
        QSqlTableModel *tableModel;
    };
    
    #endif // PERSONALLISTE_H
    

    Angezeigt werden die Beispieldaten korrekt. 😕

    Der Nala



  • nalamar schrieb:

    Angezeigt werden die Beispieldaten korrekt. 😕

    Was soll das db da? Nochdazu im Freispeicher? Lies dir doch mal erst die Beschreibung in der Doku durch, wie man eine QSqlDatabase öffnet.
    Die db die in deiner table angezeigt wird, öffnest du ganz wo anders. Kannst du das mal zeigen?



  • Ja, ich bin halt kein Profi ... ich arbeite mich langsam durch ... und der Umstieg von wx zu Qt bereitet zusätzliche schwierigkeiten.

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("gm.db");
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    


  • Mach in der Main QSqlDatabase::addDatabase("QSQLITE","DBname"); dann kannst du ÜBERALL mit QSqlDatabase::database ( const QString & connectionName = QLatin1String( defaultConnection ), bool open = true ) dir erneut genau diese DB holen ... nix DialogXY(bla) : db(new QSqlDatabase()) {} . Einfach dort wo dus auf die DB zugreifen willst:

    QSqlDatabase db = QSqlDatabase::database("DBname",false); // gib mir die DB zurück, nicht öffnen wenn noch zu!!! 
      if (db.isValid() && !db.isOpen())
      {
        // wohl noch nicht geöffnet .. dann wolln mer mal:
        db.setHostName("bla");
        db.setDatabaseName("blobb");
        db.setUserName("blubber");
        db.setPassword("hatschi");
        if (db.open())
        { /* tu was damit */}
        else 
        { qDebug() << "URRRKS .. DB geht nicht auf.";}
      }
      else if (db.isValid() && db.isOpen())
      { /* tu was damit */}
      else
      { qDebug() << "MÖÖÖÖÖÖÖÖÖP ... die DB Connection gibts nich.";}
    


  • das Passwort im Klartext zu setzen ist im übrigen .... fragwürdig ... bau dir lieber einen Dialog der Name, Passwort usw abfragt ... oder richte dir in der DB einen Namen an der NUR lesend Zugriff hat ("guest","apfelAutoKrampf") ...



  • Danke Padreigh, werds heute abend wenn ich zuhause bin gleich testen.
    Das mit dem Passwort ist zur Kenntniss genommen, dient aber im Moment dem Entwicklerzweck sehr gut .... irgendwann in ferner Zukunft soll es keine SQlite DB bleiben, dann wird auch das PW anders 😃



  • So, eben zuhause angekommen und gleich losgelegt ... Resultat ... funktioniert nicht 😞
    Folgendes hab ich in nach deinem Beispiel eigefügt:

    In der Main:

    QSqlDatabase::addDatabase("QSQLITE","DBname");
    

    In der Mainwindow.cpp

    QSqlDatabase db = QSqlDatabase::database("DBname",false); // gib mir die DB zurück, nicht öffnen wenn noch zu!!!
      if (db.isValid() && !db.isOpen())
      {
        // wohl noch nicht geöffnet .. dann wolln mer mal:
        db.setDatabaseName("gm.db");
    if (db.open())
        {
            QSqlQuery query;
            query.prepare("SELECT * FROM users WHERE uname = :name");
            query.bindValue(":name", uname);
            query.exec();
    
            QSqlRecord record = query.record();
    ...
    

    Und es kommt

    QSqlQuery::prepare: database not open

    Was ja aber eigentlich durch das "db.open" nicht sein kann ?

    der Nala

    EDIT:

    Nach der Klassenreferenz hab ich nun in der Main:

    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("gm.db");
        db.open();
    

    Womit alle meine Abfragen die ich bisher gemacht habe, problemlos funktionieren, dabei hab ich das, was l'abra d'or angemerkt hat, komplett entfernt.
    Das ganze sieht also nun wieder so aus:

    #include "produkte.h"
    #include "ui_produkte.h"
    
    produkte::produkte(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::produkte)
    {
        ui->setupUi(this);
    ...
    

    Das ändert aber eben nichts an dem Problem, das wenn ich Daten in meinem Oben genannten tableview ändere folgende Meldung kommt

    QSqlQuery::value: not positioned on a valid record



  • Und wie erstellst du jetzt dein QSqlTableModel? Evtl. kannst du mal ein komplettes Beispiel posten, damit man das ausprobieren kann (vllt. mit deiner Beispiel-DB in einem .zip).
    Es wäre auch interessant, welche Qt-Version du verwendest, hast du SQLite als externe lib eingebunden, oder die Qt-Bindled-Version verwendet? Auf welcher Plattform bist du unterwegs?



  • Umgebung:
    Windows 7
    QT SDK installiert, und alles bei den Standardeinstellung gelassen, Qt 4.6.3, benutze das mitgeliferte SQlite.

    #include <QtSql>
    #include "personalliste.h"
    #include "ui_personalliste.h"
    #include "storage.h"
    
    personalListe::personalListe(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::personalListe)
    {
        ui->setupUi(this);
        QSqlDatabase db = QSqlDatabase::database();
        QSqlTableModel *tableModel = new QSqlTableModel;
        Storage lager;
        tableModel->setTable("users");
        tableModel->select();
        switch (lager.getLevel()){
        case 10:
            tableModel->removeColumns(0,2);
            tableModel->removeColumn(3);
            tableModel->removeColumn(5);
            tableModel->removeColumns(5,8);
        case 99:
            tableModel->removeColumn(0);
        }
        tableModel->setEditStrategy(QSqlTableModel::OnFieldChange);
        ui->tableView->setModel(tableModel);
        ui->tableView->resizeColumnsToContents();
        ui->tableView->show();
    }
    
    personalListe::~personalListe()
    {
        delete ui;
    }
    

    Das tableModel erstell ich deswegen so, weil wenn ich es auf dem Stack erstelle (siehe 2. Antwort von Phlox) wird es nicht angezeigt.

    Mein Komplettes Projekt zum Downloaden:
    http://freakshare.com/files/i0qtrm0i/projekte.rar.html



  • Nachdem mir FreakShare 2x eine leere Datei gegeben hat und ich somit 20 min. warten durfte 😡 hab ich jetzt ein Programm mit einer leerern DB - kann also nix rumprobieren...
    Kannst du vllt. einfach auf www.pastebincom einen dump deiner SQL-Daten (samt schema natürlich) hochladen? (link dann hier posten) Dann kann man besser mit dem Code spielen, wenn die db funktioniert...
    Thx.



  • Sorry das FS nit hingehauen hat ....

    hier der Pastbin Link
    Klick hier

    Danke schonmal für deine Mühe



  • Scheinbar mag dich QSqlQuery nicht mehr, wenn du Spalten entfernst.
    Es funktioniert, wenn du nach dem Setzen des Model in die view im view die Spalten mit setColumnHidden versteckst.



  • noch ein Vorschlag 🙂

    .pro

    CONFIG *= qt debug
    
    void MainWindow::on_personalLoginButton_clicked() {
    /* -->  Early return ... wenn kein Name/Passwort, kein DB Zugriff */ 
    
    /* --> */    QString uname = ui->loginusername->text();
    /* --> */    QString pw = ui->loginpassword->text();
    
    /* --> */    if (uname.isEmpty() || pw.isEmpty()) 
    /* --> */    {
    /* --> */        QMessageBox::information( /* */ ) ; // was Sinnvollens, zB "Hey IDIOT, Gib was ein!" 
    /* --> Überhaupt sind diese statischen voll praktisch, da Einzeiler und auch noch dekoriert :) */        
    /* --> */        return;
    /* --> */    }
    
        //QSqlDatabase db = QSqlDatabase::database("DBname",false); // gib mir die DB zurück, nicht öffnen wenn noch zu!!!
        QSqlDatabase db = QSqlDatabase::database();
        QSqlQuery query;   
    
    /* --> */    query.prepare("SELECT * FROM users");
    /* --> */    if (! query.exec()) { qDebug() << "Query not successful: " << query.executedQuery() << " error: " << query.lastError(); return;}
    /* --> */    QSqlRecord testrec = query.record();
    /* --> */    qDebug() << query.executedQuery() << " : " << testrec.count() << " results"; // zumindest unter linux tut das nur im debug, sonst keine Ausgabe, daher CONFIG *= qt debug
    }
    

    eigentlich schade das man bei QSqlQuery's keine verbosity einstellen kann so dass die bei nem Error im DebugModus den automatisch ausgeben ... oder geht sowas?


Anmelden zum Antworten