Seite 1 von 1

MySql QTableView und Suche

Verfasst: 14. Mai 2007 15:01
von pfusterschmied
Lb. QT Freaks
Habe vor einer Woche mit C++ und QT begonnen. Bitte steinigt mich nicht mit fehlt noch der absolute Durchblick.
Zu meinem Problem:
Ich möchte ein kleines Programmschreiben, welches mir Daten aus der DB (MySQL) in einer Tablle (QTableView) anzeigt. Nun würde ich gerne eine kleine Suchfunktion integrien. Leider scheitere ich dabei total. Kann mir jemand weiterhelfen?

Ich habe im Moment 3 Files. main.cpp, mainWindow.cpp, und find.cpp.
Da mein Programm etwas umfangreicher wird, habe ich die Suchfunktion ausgelagert. In mainWindow.cpp erstelle ich die QTableView und das QSqlModel. Die DB Verbindung funktioniert und die Daten werden angezeigt. Die Suchfunktion wird in einem eigenen Widget aufgerufen. Wie kann ich nun in der DB bzw. Tabelle suchen??? Hat jemand eine Anleitung oder eine Idee.
Hier ein wenig Code:
Die find.cpp wurde aus einem Tutorial übernommen! Leider habe ich keine Ahnung wie ich diese ändern muss, wenn ich in der Tablle bzw. DB suchen will.

Code: Alles auswählen

// mainWindow.cpp
void epmanager::createWindows()
 {
	// SQL Table Model inizialisieren
	model = new QSqlTableModel(this);
	model->setTable("tx_submission_data");
                  model->setEditStrategy(QSqlTableModel::OnFieldChange);
	model->removeColumns(0,8);
	model->removeColumn(15);
	model->removeColumn(16);
	model->removeColumn(18);
	model->removeColumn(19);
	model->removeColumn(22);
	model->setSort(1, Qt::AscendingOrder);
	model->setHeaderData(0, Qt::Horizontal, QObject::tr("Vorname"));
                   model->setHeaderData(1, Qt::Horizontal, QObject::tr("Nachname"));
                  model->setHeaderData(2, Qt::Horizontal, QObject::tr("Geschlecht"));
	model->setHeaderData(18, Qt::Horizontal, QObject::tr("Startnummer"));
	model->setHeaderData(19, Qt::Horizontal, QObject::tr("Gesamt-Status"));
	model->select();

	//Detail Ansicht TableView
                  detailView = new QTableView();
	detailView->setModel(model);
	detailView->setSortingEnabled(true);
	detailView->setAlternatingRowColors(true);
                   setCentralWidget(detailView);
 
 }

Code: Alles auswählen

//find.cpp
#include <QtGui>

#include "finddialog.h"

FindDialog::FindDialog(QWidget *parent)
    : QDialog(parent)
{
    label = new QLabel(tr("Suche &nach &Name:"));
    lineEdit = new QLineEdit;
    label->setBuddy(lineEdit);

    caseCheckBox = new QCheckBox(tr("Großschreibung beachten:"));
    backwardCheckBox = new QCheckBox(tr("Suche &rueckwaerts:"));

    findButton = new QPushButton(tr("&Suchen"));
    findButton->setDefault(true);
    findButton->setEnabled(false);

    closeButton = new QPushButton(tr("Schliessen"));

    connect(lineEdit, SIGNAL(textChanged(const QString &)),
            this, SLOT(enableFindButton(const QString &)));
    connect(findButton, SIGNAL(clicked()),
            this, SLOT(findClicked()));
    connect(closeButton, SIGNAL(clicked()),
            this, SLOT(close()));

    QHBoxLayout *topLeftLayout = new QHBoxLayout;
    topLeftLayout->addWidget(label);
    topLeftLayout->addWidget(lineEdit);

    QVBoxLayout *leftLayout = new QVBoxLayout;
    leftLayout->addLayout(topLeftLayout);
    leftLayout->addWidget(caseCheckBox);
    leftLayout->addWidget(backwardCheckBox);

    QVBoxLayout *rightLayout = new QVBoxLayout;
    rightLayout->addWidget(findButton);
    rightLayout->addWidget(closeButton);
    rightLayout->addStretch();

    QHBoxLayout *mainLayout = new QHBoxLayout;
    mainLayout->addLayout(leftLayout);
    mainLayout->addLayout(rightLayout);
    setLayout(mainLayout);

    setWindowTitle(tr("Suchen und Finden"));
    setFixedHeight(sizeHint().height());
}

void FindDialog::findClicked()
{
    QString text = lineEdit->text();
    Qt::CaseSensitivity cs =
            caseCheckBox->isChecked() ? Qt::CaseSensitive
                                      : Qt::CaseInsensitive;
    if (backwardCheckBox->isChecked()) {
        emit findPrevious(text, cs);
    } else {
        emit findNext(text, cs);
    }
}

void FindDialog::enableFindButton(const QString &text)
{
    findButton->setEnabled(!text.isEmpty());
}


Re: MySql QTableView und Suche

Verfasst: 14. Mai 2007 15:10
von macman
pfusterschmied hat geschrieben:Habe vor einer Woche mit C++ und QT begonnen. Bitte steinigt mich nicht mit fehlt noch der absolute Durchblick.
Irgendwas an Programmiererfahrung da auf dem aufbauen kann?

Deine Findklasse sucht jedenfalls nicht und wird es auch nie. Die stellt nur den Suchdialog zur Verfügung und versendet ein Signal, abhängig davon auf welchen Button geklickt wurde. Die eigentliche Suchroutine wirst Du woanders einbauen müssen.

Verfasst: 14. Mai 2007 15:22
von patrik08
Keine ahnung wie deine mysql felder ausshen... wenigstens eine table structur..

wenn du den source anschaust von
http://www.qtforum.de/forum/viewtopic.php?t=4078 (ist fast wie phpMyAdmin eben dass was man braucht... )

sowie Boolean Full-Text Searches

http://dev.mysql.com/doc/refman/5.0/en/ ... olean.html

ich habe es hinbekommen die suche && trotzdem noch editierbare table ... im sqlmodel

Code: Alles auswählen



SearchModel::SearchModel( const QSqlDatabase dbin , int startat , int limit , QString searchword , QString qwhere )
{
    db = dbin;
    
    setTable(TABLE_ADDO);
    setEditStrategy(QSqlTableModel::OnRowChange);
    limitrow = limit;
    fromrow = startat;
    updatepass = 0;
    QString opgrep = QString("MATCH (NAME,FIRST_NAME,ADRESS_ROAD,ADRESS_PLACE,PLACE_OF_BIRTH,E_WEB,E_MAIL_1,VERBAENDE) AGAINST ('%1' IN BOOLEAN MODE) ").arg(searchword); 
    oniyp = true;
    
    QString doctor = searchword;
            doctor.append(qwhere);
    
    if (doctor.size() > 2) {
     oniyp = false;   
        
    }
          
    
    
        selectsql ="SELECT ";
        selectsql.append(QString("ID,KCTEXTde AS BERUF,NAME,FIRST_NAME,ADRESS_PLACE,KANTON,COUNTRY,DAY_OF_BIRTH,DEAD,"));
        selectsql.append(QString("LANGUAGE,"));
        selectsql.append(QString("DOSSIER,MUTATION"));
    
        if (searchword.size() > 3 ) {
            selectsql.append(QString(",%1 AS SCORE").arg(opgrep));
        }
        selectsql.append(QString(" FROM %1,TRBERUF ").arg(TABLE_ADDO));
        
        if (searchword.size() > 3 ) {
             selectsql.append(QString(" WHERE %1").arg(opgrep));
             selectsql.append(QString(" AND BERUFSCODE !='' AND REGI_CLASSIFICATION !='' AND KCKEY = CONCAT(REGI_CLASSIFICATION,BERUFSCODE)")); 
        } else {
           
            selectsql.append(QString(" WHERE BERUFSCODE !='' AND REGI_CLASSIFICATION !='' AND KCKEY = CONCAT(REGI_CLASSIFICATION,BERUFSCODE)"));
        }
        
        if (qwhere.size() > 3 ) {
            /////////////selectsql.append(QString(" AND "));
            selectsql.append(qwhere);
        }
        selectsql.append(QString(" LIMIT %1,%2 ").arg(fromrow).arg(limitrow));
        
        
         /////////////setQuery(selectsql,dbin);
        
    refresh();
}


void SearchModel::refresh()
{
    QSqlQuery querynow(selectsql,db);
    setQuery(querynow);
.............



Suchroutine

Verfasst: 14. Mai 2007 15:37
von pfusterschmied
Ich habe bis nur CMS und Homepages in Flash bzw. PHP programmiert.

Vielleicht habe ich mich etwas falsch ausgetrückt. Ich rufe den Find Dialog einfach mittels Menü Button auf. Wenn nun das Suchfeld ausgefüllt wird, wird der Button aktiv. Wenn darauf geklickt wird wird der SLOT findclicked() ausgeführt.

Je nach Einstellungen wird nun die Funktion: findPrevious(text, cs) bzw. findNext(text, cs) aufgerufen.

Muss ich jetzt in der Funktion die ersteugte Tabelle durchsuchen oder das erzeugte model???

Code: Alles auswählen

void mainWindow::findNext(const QString &str, Qt::CaseSensitivity cs)
{
    int row = currentRow();
    int column = currentColumn() + 1;

    while (row < RowCount) {
        while (column < ColumnCount) {
            if (text(row, column).contains(str, cs)) {
                clearSelection();
                setCurrentCell(row, column);
                activateWindow();
                return;
            }
            ++column;
        }
        column = 0;
        ++row;
    }
    QApplication::beep();
}

Danke für das Tut

Verfasst: 14. Mai 2007 15:41
von pfusterschmied
Hi patrik08, danke für das Beispiel, werde mich da mal durchkämpfen bevor ich die nächsten dummen Fragen stelle.

Re: Suchroutine

Verfasst: 14. Mai 2007 16:01
von patrik08
pfusterschmied hat geschrieben:Ich habe bis nur CMS und Homepages in Flash bzw. PHP programmiert.
Na also PHP5 Objektorientierung (OOP) hat viel gemeinsam mit eine QT class... muss nur die $ wegputzen und extends mit public ClassName ersetzen ... und __construct & __destruct mit classename mit und ohne ~ dann ist das ziel fast erreicht...

Ich habe direct mit QT angefangen vor einem Jahr ohne zu wissen wass C++ ist ... nur etwa 10 Jahre php & perl, phyton erfahrung...

beispiele von qt findet man massenweise in http://www.koders.com/
suche dort QString oder sonst qt funktionen und diese beispiele helfen sehr viel...

Koders.com

Verfasst: 14. Mai 2007 16:12
von pfusterschmied
Danke für den Link!
Werd mich mal weiter einarbeiten und vielleicht zur späterer Stunde eine konkretere Frage stellen...

Verfasst: 14. Mai 2007 19:44
von upsala
Suchen kann man i Model mit

Code: Alles auswählen

QModelIndexList QAbstractItemModel::match ( const QModelIndex & start, int role, const QVariant & value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap ) ) const 

Lösung gefunden!

Verfasst: 22. Mai 2007 10:20
von pfusterschmied
Ich hab nun eine Lösung gefunden, falls es jemanden nützt!

Zur Erklärung:
Habe ein ProxyModel von meinem QSqlModel abgeleitet. Nun kann man mit setFilterRegExp eine Abfrage definieren.
Wichtig ist dabei das neue Proxy Model der QTableView zuzuweisen setModel(proxyModel).


Code: Alles auswählen

QRegExp regExp(lineEditSearch->text(),caseSensitivity,syntax);
proxyModel->setFilterRegExp(regExp);