QListView/sq

From Qt Wiki
Jump to navigation Jump to search
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

Si të renderojmë një QListView (pjesa e tretë)

Nga dy artikujt e më hershëm pamë se si mund të bëjmë renderimin e një QListView duke shfrytëzuar një delegat (Ang. delegate). Shpesh herë na duhet që jo vetëm të bëjmë ndërrimin e ngjyrave, por edhe të japim alternativa të tjera gjatë editimit të të dhënave në një QListView.

Marrim shembullin më poshtë ku kemi prezantuar listën e thjeshtë dhe përdoruesi i aplikacionit tonë dëshiron që ti ndërroj numrat në atë listë, dhe ja se cfarë ndodhë:

4hlOR.png

Përdoruesit i shfaqet një "text box" apo në Qt quhet QLineEdit për të edituar dhe kjo mundësi i jep përdoruesit që të shkruaj edhe text jo vetëm numra:

j0Zep.png

Kjo na bjen shumë probleme dhe komplikime nëse në databazë pranojmë vetëm numra dhe nuk është e këndshme aspak për përdoruesin!

Cfarë mund të bëjmë ne që ta evitojmë këtë problem është që të shfrytëzojmë delegate mekanizmin për të krijuar metoda relevante për editim të të dhënave, dhe në rastin tonë me numra vijmë te një zgjidhje e problemit, i cili shifet në pamjën në vazhdim:

9VHGv.png

Pra i prezentojmë përdoruesit një mënyrë më relevante për editim, në rastin tonë përdorim një QSpinBox i cili lejon përdoruesin të zgjedhë numra nga një rang i ulët deri te një rang i lartë të cilin e caktojmë ne.

Se si arrihet kjo veti është implementimi i tri funksioneve virtuale të cilat i përmban QItemDelegate (i cili është prezantuar në pjesën e parë), ato funksione janë:

  • createEditor
  • updateEditorGeometry
  • setEditorData

Ta shohim implementimin e secilit:

Header skedari:

#include <QItemDelegate>
#include <QPainter>
#include <QModelIndex>
#include <QSpinBox>

class ListaDelegate : public QItemDelegate
{
 Q_OBJECT
public:
 explicit ListaDelegate(QObject *parent = 0);

protected:
 QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
 void setEditorData(QWidget *editor, const QModelIndex &index) const;
 void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

tani tregojmë implementimin e secilit funksion, dhe e spjegojmë atë

createEditor funksioni

QWidget *ListaDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
 QSpinBox *numrat = new QSpinBox(parent);
 numrat->setMinimum(0);
 numrat->setMaximum(1000);

return numrat;
}

Sic shifet në këtë funksion, krijohet një QSpinBox objekt në heap, i vendosën margjinat deri në cilin numër maksimal mund të shkojë përdoruesi, dhe kthehet ai objekt, i cili realisht shfaqet në formë.

Më pas duhet ta implementojmë updateEditorGeometry funksionin sepse i tregojmë se sa do të jetë gjërësia dhe gjatësia e Widget-it tonë pasi që të shfaqet:

void ListaDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
 QSpinBox '''numrat = static_cast<QSpinBox'''>(editor);
 numrat->setGeometry(option.rect);
}

Sic shifet ne kemi option objektin i cili na kthen një rect funksion i cili kthen QRect objekt i cili i posedon të gjitha informatat për gjeometrinë e dëshiruar, në rastin tonë e kthen gjeometrinë se sa është i gjërë një element.

Në fund dëshirojmë që në atë moment që klikohet dy herë në një element, në atë moment të merret vlera e cila është e selektuar dhe të shfaqet në editues, nëse nuk bëhet implementimi i setEditorData() funksionit, kemi rezultate të pa dëshirueshme, në këtë rast thjesht kemi 0.

Implementimi i setEditorData()

void ListaDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
 QSpinBox '''numrat = static_cast<QSpinBox'''>(editor);
 numrat->setValue(index.data().toInt());
}

Shohim se në dy rastet jemi duke përdorë static_cast i cili lejon ndërrimin e tipeve sikur nga klasa derrivuese në klasën bazë po ashtu edhe anasjelltas, nëse përdorim dynamic_cast na lejon vetëm ndërrimin e tipeve nga klasa derrivuese në klasën bazë.

Për më shumë lexoni këtë artikull: Type Casting