TableView

2011.04.13. 13:18 | arabiata | Szólj hozzá!

Címkék: select rendezés tableview qheaderview qsqlquerymodel sort direction clicked signal

Hogyan tudjuk megjeleníteni az adatbázisban tárolt adatainkat? Táblázatban vagy mezőnként. Mindkét megoldásra mutatok példát, kezdjük a táblázattal.

A TableView egy model adatait mutatja meg táblázatos formában.

 

Ehhez először meg kell határozni a modelt:

  QSqlQueryModel *model = new QSqlQueryModel;

  model->setQuery("select...");

Ha az ablak megjelenésével együtt mutatjuk meg az adatokat, akkor javasolt a konstruktorba tenni. A "select" utasításban határozzuk meg, hogy mi jelenjen meg. De mivel alapban a select-ben megadott mezőneveket teszi be a progi a header-be, ezt illik emberi formára módosítani:

model->setHeaderData(0, Qt::Horizontal, trUtf8("ID"));

model->setHeaderData(1, Qt::Horizontal, trUtf8("Megnevezés"));

model->setHeaderData(2, Qt::Horizontal, trUtf8("Indító pr."));

model->setHeaderData(3, Qt::Horizontal, trUtf8("Aktív"));

model->setHeaderData(4, Qt::Horizontal, trUtf8("Kapcs. típ."));

 A trUtf8 biztosítja az ékezetes karakterek helyes megjelenítését. A TableView fejlécét a "QHeaderView" osztály segítségével módosítom. Először megcsinálom az összerendelést.

hv = new QHeaderView(Qt::Horizontal);

widget.tableView->setHorizontalHeader(hv);

A mezők szélességét is be kell állítani:

  hv->setDefaultSectionSize(60);

  hv->resizeSection(0, 30);

  hv->resizeSection(1, 210);

  hv->resizeSection(2, 210);

  for (int i = 5; i < hv->count(); i++) {

  hv->hideSection(i);  }

 Nem fogom egyenként állítgatni őket, hanem veszek egy alapot (60) és az ettől különbözőket módosítom. A "for" ciklusban a select-ben szereplő többi mezőt elrejtem. A section-t azonosító logikai index 0-val kezdődik. A táblázat adatait rendezni is kellhet különböző mezőkre, az erre szolgáló bigyót piros körrel jelöltem.

  hv->setSortIndicatorShown(true);

  hv->setClickable(true);

  if (irany == "asc") {

    hv->setSortIndicator(1, Qt::AscendingOrder);

  } else {

    hv->setSortIndicator(1, Qt::DescendingOrder);

  }

A második sorban állítom be, hogy generálódjon clicked üzenet a fejlécre kattintásnál. A clicked üzenethez hozzárendelek egy függvényt.

  connect(hv, SIGNAL(sectionClicked(int)), this, SLOT(rendezes_slot(int)));

Az üzenet hatására a függvényre ugrik a vezérlés.

void AutomataForm::rendezes_slot(int oszlop) {

 

  if (oszlop != 1) {

    hv->setSortIndicatorShown(false);

    return;

  }

  hv->setSortIndicatorShown(true);

 

  if (hv->sortIndicatorOrder() == Qt::AscendingOrder) {

    adatok_beolvasasa("asc");

  } else {

    adatok_beolvasasa("desc");

  }

}

 Az "oszlop" változó tartalmazza a kiválasztott mező index-ét. Nálunk a megnevezés mező a szerencsés kiválasztott, így csak akkor rendezem le az adatokat, ha arra kattint a felh. A többi fejlécre kattintásnál letiltom a rendezés jelet. Az "adatok_beolvasasa" függ. paramétere a rendezés iránya, amit egyszerűen hozzámásolok a "select" utasításhoz:

void AutomataForm::adatok_beolvasasa(QString irany) {

  model->setQuery("select... order by megnevezes " + irany, db_leiro);

Mi van, ha mondjuk módosításnál az automata azonosítójára van szükségem, de bármelyik cellára kattinthat a felh.? Erre van a TableView clicked signal, amit a Qt Designer-ben rendeltem egy függvényhez.

connect(widget.tableView, SIGNAL(clicked(QModelIndex)), this,SLOT(automata_kivalasztasa_slot(QModelIndex)));

 És a függvény:

void AutomataForm::automata_kivalasztasa_slot(QModelIndex selItem) {

  automata_id = selItem.sibling(selItem.row(), 0).data().toString();

A kiválasztott cellához tartozó sor 0-s sorszámú (legelső) mezőjénak tartalmát veszem ki.

Mezőkénti adatmegjelenítésre pl. akkor van szükség, ha adatokat akarok módosítani. Tudom, erre van lehetőség a TableView vagy TableWidget osztályoknál is, de szerintem szebb, ha külön mutatom meg a módosítható adatokat. Ehhez a Qt Designer-ben felpakolom a szükséges adatbeviteli mezőket (linedit, combobox, spinbox, stb). Az előbbiekhez hasonlóan kiveszem az adatokat a táblázatból, és értékadással feltöltöm őket.

  widget.megnevezes->setText(selItem.sibling(selItem.row(), 1).data().toString());

  widget.indito_pr_neve->setText(selItem.sibling(selItem.row(), 2).data().toString());

  widget.aktiv_comboBox->setCurrentIndex(selItem.sibling(selItem.row(), 13).data().toInt() - 1);

  widget.soros_tcp_comboBox->setCurrentIndex(selItem.sibling(selItem.row(), 14).data().toInt());

 Ugye az elején láttuk, hogy csak az első öt mezőt jelenítem meg a "select" által visszaadott adatokból. A többi adat is rendelkezére áll, még ha nem is látható. Így a 13,14 a "select" vonatkozó mezőinek sorszámát jelenti. 

Az előző bejegyzés végén írtam, hogy a felhasználói adatbevitel a legveszélyesebb része a program futásának, így minél jobban korlátozni kell ezt a műveletet. Íme két példa:

Soros adatátvitelnél tudnom kell az adatbitek számát. Ez 4 - 8 érték lehet. Ha hagyom, hogy a user egy lineedit mezőbe írja be az értéket, tízből tízszer el fogja rontani, ráadásul még ellenőriznem is kell a bevitt adatot. Ezt kikerülve egy spinbox-ot használok, beállított értékekkel

 

 

 

 

 

Ha nem tudom teljesen lekorlátozni az adatbevitelt, akkor is igyekszem szűkíteni a hibalehetőségeket.

 

 

 

 

 

Itt pl. maszkolom az adatbevitelt, vagyis csak számokat vihet be. Megadok egy default értéket is, ha ettől különböző értéket kapok a vizsgálatnál, akkor valszeg jó adatot írt be.

 

 

 

A bejegyzés trackback címe:

https://qtqt.blog.hu/api/trackback/id/tr552822858

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása