QT 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.
Projemize isim veriyor ve hangi klasörde oluşturacağımızı “Browse” seçiyoruz.
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…
#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.
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…
Ücretsiz ve açık kaynak kodlu(open source) SqliteBrowser programını kullanıyoruz.
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
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.
İ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.
Neyse
text alanlarımız “Line Edit”, sırasıyla isimleri txt_adsoyad, txt_tel, txt_cep ve txt_mail
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
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.
EK, ÖRNEK PROJE
ilgili proje “Telefondefteri.pro”, QT programıyla açıyoruz..