29.6.2018
MySQL je jednou z nejrozšířenějších serverových databází. Postupně si ukážeme jak načíst a zobrazit obrázky uložené jako BLOB data v různých typech aplikací (ve smyslu použití té které knihovny pro uživatelské rozhraní a přístup k databázi). Konkrétně půjde, alespoň prozatím o tyto:
Qt Widgets
WinForms v C#
C++ a „čísté“ Windows API
Ve všech případech budeme vycházet z jedné existující databáze s tabulkou, obsahující sloupce:
id (číslo - autoincrement)
nazev - text
obrazek - longblob
velikost – číslo (int)
V dnešním článku začneme aplikací využívající knihovnu Qt. Ukázkové příklady kódu budou z testovací aplikace obsahující na hlavním a jediném okně QListWidget ve kterém budou načteny ID jednotlivých záznamů (řádků tabulky) a při změně výběru seznamu načteme obrázek a zajistíme jeho zobrazení (a samozřejmě překreslování podle potřeby) na okně aplikace.
V aplikaci postavené na knihovně Qt využijeme třídu QSqlDatabase a související třídy pro podporu SQL databází.
Databázi si otevřeme do globál proměnné nebo členské proměnné vhodné třídy (bude typu QSqlDatabase).
db = QSqlDatabase::addDatabase("QMYSQL"); db.setHostName("127.0.0.1"); db.setDatabaseName("nazev_db"); db.setUserName("user_db"); db.setPassword("heslo_db"); bool ok = db.open(); if (!ok) terminate();
Přidání obrázku ze souboru provedeme jeho načtením do objektu QByteArray který pak použijeme jako parametr instance třídy QSqlQuery jak je vidět v následujícím kódu který je volaný na výběr příslušné položky menu.
void okno_hlavni::on_pridat() noexcept { QString soubor = QFileDialog::getOpenFileName(0, QString::fromStdWString(L"Vyber obrázek"), tr("r:\\fotografie"), tr("Images (*.png *.tiff *.tif *.jpg)")); QSqlQuery q = QSqlQuery(_databaze->db); QFile file(soubor); if (!file.open(QIODevice::ReadOnly)) return; QByteArray inByteArray = file.readAll(); q.prepare("insert into obrazky (nazev, obrazek, velikost) values (:nazev, :imageData, :velikost)"); q.bindValue(":nazev", soubor); q.bindValue(":imageData", inByteArray); q.bindValue(":velikost", inByteArray.length()); if (!q.exec()) { QSqlError err = q.lastError(); this->ui.edit_nazev->setText(err.driverText() + err.databaseText()); } naplnit_seznam(); }
Fukce která naplní seznam (QListWidget) vypadá takto:
void okno_hlavni::naplnit_seznam() noexcept { ui.list_seznam->clear(); QSqlQuery q = QSqlQuery("select id, nazev from obrazky", _databaze->db); while (q.next()) { ui.list_seznam->addItem(q.value(0).toString()); } }
Přidání obrázku tedy máme hotové, nyní zbývá při změně výběru načít aktuální obrázek do objektu QPixmap a zajistit jeho zobrazení a překreslování podle potřeby.
Funkci zmena_vyberu si připojíme k události currentItemChanged v konstruktoru třídy okna aplikace:
connect(ui.list_seznam, &QListWidget::currentItemChanged, this, &okno_hlavni::zmena_vyberu);
Funkce pak vypadá takto?
void okno_hlavni::zmena_vyberu(QListWidgetItem *current, QListWidgetItem *previous) noexcept { if (nullptr == current) return; QSqlQuery q = QSqlQuery("select * from obrazky where id = " + current->text(), _databaze->db); if (!q.next()) return; this->ui.edit_nazev->setText(q.value(1).toString()); this->pixmap.loadFromData(q.value(2).toByteArray()); this->repaint(); }
Jak je zřejmé hned po načtení vyvoláme bezprostřední překreslení okna, o následná vyvolání se již stará systém, my musíme pouze napsat vlastní metodu paintEvent v naší třídě okna (odvozené od QMainWindow):
void okno_hlavni::paintEvent(QPaintEvent* q) { QPainter p(this); if (this->pixmap.isNull()) return; p.drawPixmap(300, 50, this->pixmap); }
Školení
Kontakt
739 219 991
live:radekchalupa_1
Nové články