QT C++ SQLITE ile Telefon Defteri

telefon-defteriQT DESIGNER 4.0.0 ile SQLITE Kullanarak Telefon Defteri yapıyoruz. (resimleri, üzerine tıklayarak orijinal boyutlarda görebilirsiniz)

Programı Buradan İndiriyor ve Kuruyoruz

Programı çalıştırıyoruz. Karşılama ekranında “New Project” diyoruz veya “File” menüsünden “New File or Project..” tıklıyoruz.

proje_olustur

Projemize isim veriyor ve hangi klasörde oluşturacağımızı “Browse” seçiyoruz.

proje_olustur2

ana_ekran

Tüm dosyalarımız oluşturuldu…

mainwindow.h” dosyasına çift tıklıyor ve düzenliyoruz. Üst bölüme kullanılacak kütüphaneleri ekliyoruz.

Giriş kısımı şu şekilde olmalı.

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtSql>
#include <QtDebug>
#include <QRect>
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlQueryModel>

SQLITE kullanacağız, bu halde SQL işlemleri için gerekli kütüphaneleri eklememiz gerekiyor. Bunlar (<QtSql>,<QSqlQuery>)

Pencere genişleyip daraldığında içerideki alanlarında buna göre pozisyon alması ve ölçümler için (<QRect>) kütüphanesini ekliyoruz.

<QMessageBox> ise mesaj penceresi için…

mainwindow.h” içeriği

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QtSql>
#include <QtDebug>
#include <QRect>
#include <QMessageBox>
#include <QSqlQuery>
#include <QSqlQueryModel>


namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void on_btn_kaydet_clicked();
    void on_tbl_liste_doubleClicked(const QModelIndex &index);
    void on_btn_yeni_clicked();
    void on_btn_sil_clicked();
    void on_btn_sil_2_clicked();
    void on_txt_ara_textChanged(const QString &arg1);

private:
    Ui::MainWindow *ui;
    void resizeEvent(QResizeEvent* evt) Q_DECL_OVERRIDE;
    void listele(QString sql);
};

#endif // MAINWINDOW_H

Burada kullanacağımız sınıflar ve fonksiyonları tanımlıyoruz, “kullanıcı fonksiyonları” olarak 2 adet bize özel fonksiyonumuz olacak(diğerleri program tarafından otomatik oluşturulacak).

void resizeEvent(QResizeEvent* evt) Q_DECL_OVERRIDE;
void listele(QString sql);

resizeEvent fonksiyonu, pencerenin(form) ebadlarının anlık değiştirilmesine göre tetiklenen fonksiyondur.(Böylece kullandığımız bileşenleri ekrana göre konumlandırabileceğiz)

listele fonksiyonu ise, kullanacağımız “QTableView” bileşeninin güncelenmesi için.

Bu dosya ile işimiz buraya kadar(dosyada tanımlamalar, yukarıda özellikle belirttiğim 2 fonksiyon hariç, QT programı ile otomatik oluşturulacaktır)

Şimdi sıra PROJE dosyamızda QT değişkenine, “sql“‘ide eklemeye geldi.

TelefonDefteri.pro” işlemler

ilgili dosyayı açtığımızda

QT += core gui

bu satırı göreceğiz, ardına “sql” eklememiz gerekir.

QT += core gui sql

Bu dosya ile de işimiz bitti…

SQLITE Database oluşturmak

Ücretsiz ve açık kaynak kodlu(open source) SqliteBrowser programını kullanıyoruz.

http://sqlitebrowser.org/

Kullandığımız işletim sistemine göre indirip, kuruyor ve programı çalıştırıyoruz.

New Database diyoruz ve yeni veritabanımızı ilgili proje dosyamızın olduğu dizinde oluşturuyoruz(örnek projede “database.db” ismiyle oluşturdum)

Sonra ilgili programda “Execute SQL” kısmını açıp alanları ekleyelim(aşağıdaki kodları olduğu gibi kopyalayıp, yapıştırabilirsiniz)..

CREATE TABLE `TELEFON` (
    `id`    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    `adsoyad`    TEXT,
    `telefon`    TEXT,
    `cep`    TEXT,
    `mail`    TEXT
);

veya

“Database Structure” kısmında “Create Database” tıklayıp tablo ismi(“TELEFON”) verdikten sonra tek, tek alanları oluşturabilirsiniz(ilgili ekranda “Add field” butonu).

database.db dosyamızın, Proje ile aynı klasörde olduğuna dikkat etmeliyiz, çünkü “mainwindow.cpp” açılışında, ilgili dosyanın bulunduğumuz dizinde(current directory) olduğunu belirteceğiz…

Resimde görüldüğü gibi

database-yol

FORM ALANLARININ OLUŞTURULMASI “mainwindow.ui

programda, “mainwindow.ui” tıklıyor ve açıyoruz, karşımıza tasarım(design) ekranı gelecek…

İlk etap, sol bileşen menüsünden 1 adet “Widget” ekliyoruz, bu tüm diğerleri için dış conteyner(container) olacak, böylece tüm diğer elemanları derli toplu biçimde, dahili tutacağız.

tasarim-ekrani

İlgili alanların arka plan, font vb renkleri, kullanımına dair burada detay vermeyeceğim, zira ekte vereceğim örnek projede ilgili alanlara sağ tıklayıp, ilgili style kodlarını görebilirsiniz.

style-islemleri

Neyse

text alanlarımız “Line Edit”, sırasıyla isimleri txt_adsoyad, txt_tel, txt_cep ve txt_mail

mainwindow.cpp” Asıl işi yaptığımız dosya

Girişte, “mydb” değişkenimizin bir database sınıfı olacağını ve “SQLITE” kullanacağımızı belirtiyoruz.

İçinde bulunduğumuz dizini buluyoruz (pwd = QDir::currentPath();)

böylece database.db dosyamıza bağlantı sağlıyoruz.

mydb.setDatabaseName(pwd);

#include "mainwindow.h"
#include "ui_mainwindow.h"

// database
QSqlDatabase mydb = QSqlDatabase::addDatabase("QSQLITE");

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->txt_id->hide();
    // EKRANI KAPLA (!)
    QMainWindow::showMaximized();
    // veritabani yol (current path)
    QString pwd = "";
    pwd = QDir::currentPath();

    pwd += "/database.db";
    pwd.replace("\\","/");
    mydb.setDatabaseName(pwd);

    QMessageBox msg;
    // BAGLANILAMAZSA HATA BILDIR
    if(!mydb.open()) {
        msg.setWindowTitle("Hata");
        msg.setText("Veritabanı Bağlantısı Yapılamadı.");
        msg.setIcon(QMessageBox::Information);
        msg.exec();
    } else {
        QString sql = "SELECT *FROM TELEFON";
        listele(sql);
    }
    ui->txt_adsoyad->setFocus();
}

// TABLOYU SORGUYA GORE LISTELE (FONKSIYON)
void MainWindow::listele(QString sql) {
    QSqlQuery query(mydb);
    QSqlQueryModel *model = new QSqlQueryModel();
    //ui->txt_adsoyad->setText(sql);
    query.exec(sql);
    model->setQuery(query);
    ui->tbl_liste->setModel(model);
    ui->tbl_liste->hideColumn(0);
    ui->tbl_liste->setColumnWidth(1,200);
    ui->tbl_liste->setColumnWidth(4,140); // email alanı
}

// PENCERE GENISLERSE WIDGET ORTALA
void MainWindow::resizeEvent(QResizeEvent *){
    QPoint ort = ( MainWindow::window()->rect().center() - ui->widget->rect().center());
    ui->widget->move(ort);
}

MainWindow::~MainWindow(){
    delete ui;
}

// KAYIT ISLEMLERI
void MainWindow::on_btn_kaydet_clicked(){
    QMessageBox msg;
    QString adsoyad = ui->txt_adsoyad->text().trimmed();
    int id = ui->txt_id->text().toInt();
    //ui->txt_telefon->setText(QString::number(id));
    ui->txt_adsoyad->setText(adsoyad);
    if(adsoyad == "") {
        msg.setText("Ad Soyad Boş Bırakılamaz!");
        msg.exec();
    }
    else {
        QString telefon = ui->txt_telefon->text().trimmed();
        QString cep = ui->txt_cep->text().trimmed();
        QString mail = ui->txt_mail->text().trimmed();
        // guncelle
        if(id > 0) {
            QString sql = "UPDATE TELEFON SET adsoyad='"+adsoyad+"', "
                        "telefon='" + telefon + "', cep='"+cep+"', mail='"+mail+"'"
                        " WHERE id="+QString::number(id);

            QSqlQuery query(mydb);
            int rc = query.exec(sql);
            if(rc == true) {
                msg.setWindowTitle("İşlem Tamam");
                msg.setText("Güncellendi");
                msg.setIcon(QMessageBox::Information);
                msg.exec();
                sql = "SELECT *FROM TELEFON";
                listele(sql);

            } else {
                msg.setWindowTitle("Hata");
                msg.setText("HATA"+query.lastError().text());
                msg.setIcon(QMessageBox::Warning);
                msg.exec();
            }
        }
        //kaydet
        else {
            QString sql = "INSERT INTO TELEFON VALUES(NULL,'"+adsoyad+"','"+telefon+"',"
                            "'"+cep+"','"+mail+"');";

            QSqlQuery query(mydb);
            int rc = query.exec(sql);
            if(rc == true) {
                sql = "SELECT *FROM TELEFON";
                listele(sql);
                QString son_id = query.lastInsertId().toString();
                ui->txt_id->setText(son_id);
                msg.setWindowTitle("İşlem Tamam");
                msg.setText("Kaydedildi");
                msg.setIcon(QMessageBox::Information);
                msg.exec();
            } else {
                msg.setWindowTitle("Hata");
                msg.setText("HATA"+query.lastError().text());
                msg.setIcon(QMessageBox::Warning);
                msg.exec();
            }
        } // guncelle - kaydet
    } // else
}

//TABLE VIEW alanındaki içerikleri al ve kutulara yansıt
void MainWindow::on_tbl_liste_doubleClicked(const QModelIndex &index){
    if (index.isValid()) {
        QString id = index.sibling(index.row(), 0).data().toString();
        QString adsoyad = index.sibling(index.row(), 1).data().toString();
        QString telefon = index.sibling(index.row(), 2).data().toString();
        QString cep = index.sibling(index.row(), 3).data().toString();
        QString mail = index.sibling(index.row(), 4).data().toString();
        ui->txt_id->setText(id);
        ui->txt_adsoyad->setText(adsoyad);
        ui->txt_telefon->setText(telefon);
        ui->txt_cep->setText(cep);
        ui->txt_mail->setText(mail);
    }
}

// YENI KAYIT TIKLANIRSA TUM TEXT ALANLARINI BOSALT
void MainWindow::on_btn_yeni_clicked(){
    ui->txt_id->setText("");
    ui->txt_adsoyad->setText("");
    ui->txt_telefon->setText("");
    ui->txt_cep->setText("");
    ui->txt_mail->setText("");
    ui->txt_adsoyad->setFocus();
}

void MainWindow::on_btn_sil_clicked(){
    QMessageBox msgBox;

    int id = ui->txt_id->text().toInt();
    if(id <1 ) {
        msgBox.setWindowTitle("Hata");
        msgBox.setText("Kayıt Seçilmemiş.");
        msgBox.setIcon(QMessageBox::Information);
        msgBox.exec();
        return;
    }
    msgBox.setWindowTitle("İşlemi Onayla");
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText("İşlemin geri dönüşü yoktur. Emin misiniz?");
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
    msgBox.setDefaultButton(QMessageBox::Cancel);
    int ret = msgBox.exec();
    if(ret == QMessageBox::Yes ) {
        QString sql = "DELETE FROM TELEFON WHERE id="+QString::number(id);
        QSqlQuery query(mydb);
        query.exec(sql);
        on_btn_yeni_clicked();
        sql = "SELECT *FROM TELEFON";
        listele(sql);
    }
}

void MainWindow::on_btn_sil_2_clicked(){
    exit(0);
}

void MainWindow::on_txt_ara_textChanged(const QString &arg1){
    QString sql = "SELECT *FROM TELEFON WHERE adsoyad LIKE '%"+arg1+"%'";
    listele(sql);
}

Aslında kodlardan da anlaşılacağı üzere

ui->txt_adsoyad->setText(/* yeni icerik */);

adsoyad kutusuna yeni içerik atamamızı sağlar.

ui->txt_adsoyad->text(/* kutudaki icerik */).trimmed();

->text() fonksiyonu ise, ilgili alanın içeriğini almamızı sağlar, sonraki trimmed() fonksiyonu ise sağlı, sollu boşlukları kırpmamızı sağlar.

önemli olan konuya değinmiş oldum, text kutusundan içerik almak veya atamak. Bundan sonrası alınan içeriğin kontrolü ve elbette veritabanına eklenmesi sorunudur.

SQLITE Kullanımı da, MYSQL kullanımı gibidir… Sorgu stringi(cümlesi) oluşturup, sonrasında bunu işlemek mantığına dayalı.

örneğin yukarıdaki kodlara göre KAYIT kısmında, önce txt_id değerine bakıyoruz, eğer “0” ise demek ki bu bir yeni kayıttır, değilse güncellemedir. KAYDETME işlemi(MYSQL gibi)

QString sql = "INSERT INTO TELEFON VALUES(NULL,'"+adsoyad+"','"+telefon+"',"
					 "'"+cep+"','"+mail+"');";

QSqlQuery query(mydb);
// SORGUYU İŞLE
int rc = query.exec(sql);

 

DEBUG İŞLEMLERİ

RELEASE seçmek ve çıktı dizinini seçmek

release-ve-klasor

Böylece debug ve release dosyaları, projeminizin olduğu dizinde olacak, bu işlemi yapmasaydık, projenin bir üstünde-dışında oluşturacaktı…

daha sonra sol aşağıdaki, Yeşil Play butonuna basıp derlemeyi yapıyoruz.

Şimdi Release klasörü içinde “.exe” dosyamız oluşturuldu.

Ancak eksikler var, birincisi database.db dosyamız orada değil, bir dış klasörden kopyalayıp, bu klasöre atıyoruz.

Fakat hala sorunlar bitmedi, “.dll” dosyaları eksik hatası alıyoruz ve programımız çalışmıyor, o halde ilgili “.dll” dosyalarını da bulup eklememiz gerekecek.

peki hangi dosyalar bize gerekli?

Kestirme bir yol olarak şu programı tavsiye ediyorum;

Dependency Walker

Buradan indiriyor ve kuruyoruz

http://www.dependencywalker.com/

programı çalıştırıp Release dosyasındaki “.exe” dosyamızı SEÇİYORUZ, şimdi ekranda hangi “.dll” DOSYALARININ EKSİK OLDUĞUNU KIRMIZI YAZI RENGİYLE GÖRÜYORUZ.

Peki gerekli dosyalar nerede?

QT programının bulunduğu dizini açıyoruz(bendeki aşağıdaki gibi, QT ana klasör içinde versiyon klasörü içinde aşağıdaki dizine geçiyoruz).

C:\Qt\5.6\mingw49_32\bin

EKSK “.DLL” dosyalarını buluyor kopyalıyor ve release dosyamıza yapıştırıyoruz. Aşağıdaki rResimde ilgili “.dll” dosyaları işaretlendi.

release-ve-dll

EK, ÖRNEK PROJE

TelefonDefteri

ilgili proje “Telefondefteri.pro”, QT programıyla açıyoruz..

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir