Tutorial Qt - 3. Widget-uri simple

Tutorial Qt - 3. Widget-uri simple

Postby morpheus » 07 May 2010, 23:27

Tutorial Qt



Lectia 3. Widget-uri simple



Status: In progress

Qt dispune de o paleta larga de widget-uri. In aceasta lectie, vom arata cum se pot folosi cele mai des intalnite dintre ele.
Aceasta lectie consta dintr-o serie de programe minimale, care demonstreaza functionalitatea unui anumit widget.
Unele dintre widget-uri au fost deja folosite in lectia precedenta, deci ar trebui sa fiti familiarizati cu ele.

Butoane

Un buton este reprezentat de clasa QPushButton.
In exemplul de mai jos, afisam de cate ori a fost apasat un buton.

Buton in Qt

  1.  
  2. //widget.h
  3. #ifndef WIDGET_H
  4. #define WIDGET_H
  5.  
  6. #include <QtGlobal>
  7. #include <QtGui/QWidget>
  8.  
  9. class QPushButton;
  10.  
  11. class Widget : public QWidget
  12. {
  13.     Q_OBJECT
  14.  
  15. public:
  16.     Widget(QWidget *parent = 0);
  17.     ~Widget();
  18.  
  19. public slots:
  20.     void onClicked();
  21.  
  22. private:
  23.     QPushButton* m_button;
  24.     quint32 m_clickCounter;
  25. };
  26. #endif // WIDGET_H
  27.  
 

Declaram o clasa widget, care deriveaza din QWidget. Aceasta contine un membru de tip QPushButton (m_button) si un contor care tine minte de cate ori am apasat pe buton (m_clickCounter).
Declaram slot-ul onClicked(), care va fi chemat ori de cate ori apasam pe buton.

  1.  
  2. // widget.cpp
  3. #include <QtGui/QPushButton>
  4. #include <QtGui/QHBoxLayout>
  5. #include "widget.h"
  6.  
  7. Widget::Widget(QWidget *parent)
  8.     : QWidget(parent), m_clickCounter(0)
  9. {
  10.     m_button = new QPushButton();
  11.     m_button->setText(QString::number(m_clickCounter));
  12.     connect(m_button, SIGNAL(clicked()), this, SLOT(onClicked()));
  13.  
  14.     QHBoxLayout *layout = new QHBoxLayout();
  15.     layout->addWidget(m_button);
  16.     setLayout(layout);
  17. }
  18.  
  19. Widget::~Widget()
  20. {
  21.  
  22. }
  23.  
  24. void Widget::onClicked()
  25. {
  26.     m_clickCounter++;
  27.     m_button->setText(QString::number(m_clickCounter));
  28. }
  29.  


Setam textul butonului m_button astfel incat sa contina valoarea membrului m_clickCounter.
Conectam semnalul clicked al butonului m_button la slot-ul onClicked().

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include "widget.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     QApplication a(argc, argv);
  9.     Widget widget;
  10.     widget.setGeometry(400, 400, 200, 100);
  11.     widget.setWindowTitle(QObject::tr("Simple Button"));
  12.     widget.show();
  13.     return a.exec();
  14. }
  15.  


Instantiem un widget de tip Widget.

Butoane Radio

Un buton radio este reprezentat de catre clasa QRadioButton.
Butoanele radio se pot asocia intr-un grup (QGroupBox), caz in care numai unul din butoanele radio apartinand grupului poate fi selectat.

In exemplul de mai jos, utilizatorul poate select limbajul preferat, dintre urmatoarele: C++, Java, C#.

Buton radio in Qt

  1.  
  2. // radiobutton.h
  3. #ifndef RADIOBUTTON_H
  4. #define RADIOBUTTON_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QRadioButton;
  9. class QGroupBox;
  10. class QLabel;
  11.  
  12. class RadioButton : public QWidget
  13. {
  14.     Q_OBJECT
  15.  
  16. public:
  17.     RadioButton(QWidget *parent = 0);
  18.     ~RadioButton();
  19.  
  20. public slots:
  21.     void onCppSelection();
  22.     void onJavaSelection();
  23.     void onCSharpSelection();
  24.  
  25. private:
  26.     QRadioButton* m_cppButton;
  27.     QRadioButton* m_javaButton;
  28.     QRadioButton* m_csharpButton;
  29.     QGroupBox* m_languagesGroup;
  30.     QLabel* m_optionLabel;
  31. };
  32.  
  33. #endif // RADIOBUTTON_H
  34.  


Clasa RadioButton contine trei membri de tip QRadioButton, corespunzand celor trei butoane radio (cate unul pentru fiecare limbaj):
- m_cppButton , pentru limbajul C++
- m_javaButton, pentru limbajul Java
- m_csharpButton, pentru limbajul C#

Avem un grup (m_languagesGroup), in care vor fi adaugat butoanele radio.

Mai avem un label, m_optionLabel, care va afisa selectia curenta.

Sunt declarate trei slot-uri, care vor fi apelate cand fiecare dintre cele trei butoane vor fi selectate:
- onCppSelection(), va fi apelat atunci cand butonul m_cppButton va fi selectat
- onJavaSelection(), va fi apelat atunci cand butonul m_javaButton va fi selectat
- onCSharpSelection(), va fi apelat atunci cand butonul m_csharpButton va fi selectat

  1.  
  2. // radiobutton.cpp
  3. #include <QtGui/QRadioButton>
  4. #include <QtGui/QGroupBox>
  5. #include <QtGui/QLabel>
  6. #include <QtGui/QVBoxLayout>
  7.  
  8. #include "radiobutton.h"
  9.  
  10. RadioButton::RadioButton(QWidget *parent)
  11.     : QWidget(parent)
  12. {
  13.     m_cppButton = new QRadioButton(tr("C++"));
  14.     connect(m_cppButton, SIGNAL(clicked()), this, SLOT(onCppSelection()));
  15.     m_javaButton = new QRadioButton(tr("Java"));
  16.     connect(m_javaButton, SIGNAL(clicked()), this, SLOT(onJavaSelection()));
  17.     m_csharpButton = new QRadioButton(tr("C#"));
  18.     connect(m_csharpButton, SIGNAL(clicked()), this, SLOT(onCSharpSelection()));
  19.  
  20.     m_cppButton->setChecked(true);
  21.  
  22.     QVBoxLayout *groupLayout = new QVBoxLayout;
  23.     groupLayout->addWidget(m_cppButton);
  24.     groupLayout->addWidget(m_javaButton);
  25.     groupLayout->addWidget(m_csharpButton);
  26.     groupLayout->addStretch(1);
  27.  
  28.     m_languagesGroup = new QGroupBox(tr("Programming languages:"), this);
  29.     m_languagesGroup->setLayout(groupLayout);
  30.  
  31.     m_optionLabel = new QLabel;
  32.     m_optionLabel->setText("Your favorite language is C++");
  33.  
  34.     QVBoxLayout *widgetLayout = new QVBoxLayout;
  35.     widgetLayout->addWidget(m_languagesGroup);
  36.     widgetLayout->addWidget(m_optionLabel);
  37.     setLayout(widgetLayout);
  38. }
  39.  
  40. RadioButton::~RadioButton()
  41. {
  42.  
  43. }
  44.  
  45. void RadioButton::onCppSelection()
  46. {
  47.     m_optionLabel->setText("Your favorite language is C++");
  48. }
  49.  
  50. void RadioButton::onJavaSelection()
  51. {
  52.     m_optionLabel->setText("Your favorite language is Java");
  53. }
  54.  
  55. void RadioButton::onCSharpSelection()
  56. {
  57.     m_optionLabel->setText("Your favorite language is C#");
  58. }
  59.  


In constructor:
- se creeaza butoanele radio si se adauga in grup
- se creeaza label-ul
- se conecteaza semnalele click ale butoanelor radio la sloturile corespunzatoare.
In fiecare slot, se actualizeaza textul continut in m_optionLabel, ca sa reflecte optiunea curenta a utilizatorului.

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include "radiobutton.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     QApplication app(argc, argv);
  9.     RadioButton radioButtons;
  10.     radioButtons.setGeometry(400, 400, 200, 100);
  11.     radioButtons.setWindowTitle(QObject::tr("Radio Buttons"));
  12.     radioButtons.show();
  13.     return app.exec();
  14. }
  15.  


Se instantiaza un widget de tip RadioButton

Checkbox

Reprezentat de clasa QCheckbox

In exemplul de mai jos, titlul ferestrei se schimba dupa ce utilizatorul a activat/dezactivat checkbox-ul.

CheckBox in Qt

  1.  
  2. // checkbox.h
  3. #ifndef CHECKBOX_H
  4. #define CHECKBOX_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QCheckBox;
  9.  
  10. class CheckBox : public QWidget
  11. {
  12.     Q_OBJECT
  13.  
  14. public:
  15.     CheckBox(QWidget *parent = 0);
  16.     ~CheckBox();
  17.  
  18. public slots:
  19.     void stateChanged(int state);
  20.  
  21. private:
  22.     QCheckBox* m_checkBox;
  23. };
  24.  
  25. #endif // CHECKBOX_H
  26.  


Declaram clasa CheckBox, care va contine un obiect de tip QCheckBox (m_checkBox). In momentul in care starea checkbox-ului se va schimba, acesta va emite semnalul stateChanged(int).
Declaram un slot, denumit tot stateChanged, in clasa CheckBox. Acest slot va fi apelat in momentul in care semnalul va fi emis.

Implementarea clasei:

  1.  
  2. // checkbox.cpp
  3. #include <QtGui/QCheckBox>
  4. #include <QtGui/QLabel>
  5. #include <QtGui/QHBoxLayout>
  6.  
  7. #include "checkbox.h"
  8.  
  9. CheckBox::CheckBox(QWidget *parent)
  10.     : QWidget(parent)
  11. {
  12.     m_checkBox = new QCheckBox;
  13.     m_checkBox->setChecked(false);
  14.     connect(m_checkBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));
  15.     setWindowTitle(tr("Unchecked"));
  16.  
  17.     QLabel* label = new QLabel;
  18.     label->setText("Click on the checkbox: ");
  19.     QHBoxLayout* layout = new QHBoxLayout;
  20.     layout->addWidget(label);
  21.     layout->addWidget(m_checkBox);
  22.  
  23.     setLayout(layout);
  24. }
  25.  
  26. CheckBox::~CheckBox()
  27. {
  28.  
  29. }
  30.  
  31. void CheckBox::stateChanged(int state)
  32. {
  33.     if (state == Qt::Checked)
  34.         setWindowTitle(tr("Checked"));
  35.     else
  36.         setWindowTitle(tr("Unchecked"));
  37. }
  38.  


  1.  
  2. m_checkBox->setChecked(false);
  3.  

Starea initiala a checkbox-ului est unchecked

  1.  
  2. connect(m_checkBox, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));
  3.  

Conectam semnalul stateChanged(int), emis de catre m_checkBox, la slotul stateChanged(int) din clasa CheckBox

  1.  
  2. setWindowTitle(tr("Unchecked"));
  3.  

Setam titlul initial al ferestrei la valoarea Unchecked

  1.  
  2. QLabel* label = new QLabel;
  3. label->setText("Click on the checkbox: ");
  4.  

Cream un label, si setam textul ce va fi afisat

  1.  
  2. QHBoxLayout* layout = new QHBoxLayout;
  3. layout->addWidget(label);
  4. layout->addWidget(m_checkBox);
  5.  

Cream un layout de tip orizontal si adaugam label-ul si checkbox-ul in el


Setam layout-ul widget-ului nostru.

  1.  
  2. void CheckBox::stateChanged(int state)
  3.  

Acesta este slot-ul ce va fi apelat dupa ce utilizatorul va schimba stare checkbox-ului.
Daca checkbox-ul este checked, slot-ul va primi parametrul Qt::Checked, ia titlul ferestrei va fi setat la Checked
Altfel, daca checkbox-ul este unchecked, slot-ul va primit parametrul Qt::Unchecked, iar titlul ferestrei va fi setat la Unchecked.

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include "checkbox.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     QApplication app(argc, argv);
  9.     CheckBox checkBox;
  10.     checkBox.setGeometry(400, 400, 200, 100);
  11.     checkBox.show();
  12.     return app.exec();
  13. }
  14.  


Se instaintiaza un obiect de tip CheckBox, se seteaza dimensiunile si pozitia pe ecran si se afiseaza.

QLineEdit

Widget-ul QLineEdit este folosit pentru a introduce o linie de text.
In exemplul de mai jos, vom realiza un widget asemenator unui dialog de log-in.

QLineEdit in Qt

Exemplul va oferi urmatoarele functionalitati:

- utilizatorul va introduce un user-name si o parola
- in urma apasarii butonului Submit sau a apasarii tastei Enter, va fi afisat un Message Box cu datele introduse
- daca datele sunt incomplete (user-name-ul sau parola nu au fost introduse, se va afisa un mesaj de eroare
- in urma apasarii tastei ESC, se va inchide aplicatia

Declaram o noua clasa pentru widget-ul nostru, LineEdit:

  1.  
  2. // lineedit.h
  3. #ifndef LINEEDIT_H
  4. #define LINEEDIT_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QLineEdit;
  9. class QPushButton;
  10.  
  11. class LineEdit : public QWidget
  12. {
  13.     Q_OBJECT
  14.  
  15. public:
  16.     LineEdit(QWidget *parent = 0);
  17.     ~LineEdit();
  18.  
  19.     void keyPressEvent(QKeyEvent* event);
  20.  
  21. public slots:
  22.     void onSubmit();
  23.     void onClear();
  24.  
  25. private:
  26.     QLineEdit* m_userName;
  27.     QLineEdit* m_password;
  28.     QPushButton* m_submit;
  29.     QPushButton* m_clear;
  30. };
  31.  
  32. #endif // LINEEDIT_H
  33.  


Widget-ul nostru va contine doua controale de tip QLineEdit:
- m_userName folosit pentru a introduce user-name-ul
- m_password folosit pentru a introduce parola

De asemenea, avem doua butoane:
- m_submit, folosit pentru a valida datele
- m_clear, folosit pentru a sterge datele introduse

Am declarat doua slot-uri:
- onSubmit(), apelat atunci cand utilizatorul apasa butonul m_submit
- onClear(), apelat atunci cand utilizatorul apasa butonul m_clear

Implementarea clasei LineEdit este urmatoarea:

  1.  
  2. // lineedit.cpp
  3. #include <QApplication>
  4. #include <QtGui/QLineEdit>
  5. #include <QtGui/QPushButton>
  6. #include <QtGui/QLabel>
  7. #include <QtGui/QGridLayout>
  8. #include <QtGui/QVBoxLayout>
  9. #include <QtGui/QHBoxLayout>
  10. #include <QtGui/QMessageBox>
  11. #include <QtGui/QKeyEvent>
  12.  
  13. #include "lineedit.h"
  14.  
  15. LineEdit::LineEdit(QWidget *parent)
  16.     : QWidget(parent)
  17. {
  18.     m_userName = new QLineEdit;
  19.     QLabel* nameLabel = new QLabel;
  20.     nameLabel->setText(tr("User name"));
  21.  
  22.     m_password = new QLineEdit;
  23.     QLabel* passwordLabel = new QLabel;
  24.     m_password->setEchoMode(QLineEdit::Password);
  25.     passwordLabel->setText(tr("Password"));
  26.  
  27.     m_submit = new QPushButton;
  28.     m_submit->setText(tr("Submit"));
  29.     m_submit->setToolTip(tr("Submit"));
  30.  
  31.     connect(m_submit, SIGNAL(clicked()), this, SLOT(onSubmit()));
  32.  
  33.     m_clear = new QPushButton;
  34.     m_clear->setText(tr("Clear"));
  35.     m_clear->setToolTip(tr("Clear"));
  36.  
  37.     connect(m_clear, SIGNAL(clicked()), this, SLOT(onClear()));
  38.  
  39.     QGridLayout* gridLayout = new QGridLayout;
  40.     gridLayout->addWidget(nameLabel, 0, 0);
  41.     gridLayout->addWidget(m_userName, 0, 1);
  42.     gridLayout->addWidget(passwordLabel, 1, 0);
  43.     gridLayout->addWidget(m_password, 1, 1);
  44.  
  45.     QHBoxLayout* hLayout = new QHBoxLayout;
  46.     hLayout->addWidget(m_submit);
  47.     hLayout->addWidget(m_clear);
  48.  
  49.     QVBoxLayout* topLayout = new QVBoxLayout;
  50.     topLayout->addLayout(gridLayout);
  51.     topLayout->addLayout(hLayout);
  52.  
  53.     setLayout(topLayout);
  54. }
  55.  
  56. LineEdit::~LineEdit()
  57. {
  58.  
  59. }
  60.  
  61. void LineEdit::onSubmit()
  62. {
  63.     if (m_userName->text().size() == 0)
  64.     {
  65.         QMessageBox::critical(this, tr("Incomplete data"),
  66.                                      tr("Please enter your user name!"));
  67.         m_userName->setFocus();
  68.         return;
  69.     }
  70.     if (m_password->text().size() == 0)
  71.     {
  72.         QMessageBox::critical(this, tr("Incomplete data"),
  73.                                      tr("Please enter a password!"));
  74.         m_password->setFocus();
  75.         return;
  76.     }
  77.  
  78.     QString dataEntered = tr("User name: %1\nPassword: %2");
  79.     QMessageBox::information(this, tr("Data entered"),
  80.                              dataEntered.arg(m_userName->text()).arg(m_password->text()));
  81. }
  82.  
  83. void LineEdit::onClear()
  84. {
  85.     m_userName->clear();
  86.     m_password->clear();
  87.     m_userName->setFocus();
  88. }
  89.  
  90. void LineEdit::keyPressEvent(QKeyEvent* event)
  91. {
  92.     if (event->key() == Qt::Key_Return)
  93.         onSubmit();
  94.     else if (event->key() == Qt::Key_Escape)
  95.         qApp->quit();
  96. }
  97.  


Aceasta aplicatie introduce un nou tip de layout, QGridLayout. Intr-un QGridLayout controalele sunt asezate ca intr-o matrice. Utilizatorul foloseste doi indici pentru a specifica pozitia unui widget in matrice.

De exemplu:
(0,0) -> reprezinta prima linie si prima coloana
(0,1) -> reprezinta prima linia si coloana a doua
(1,0) -> reprezinta a doua linie si prima coloana
(1,1) -> reprezinta a doua linie si a doua coloana

Se observa ca valorile indicilor incep de la zero.

Se pot realiza design-uri complexe folosind layout-uri, folosindu-ne de faptul ca layout-urile pot fi imbricate (un layout poate contine alt layout).
Pentru a vedea cum se realizeaza acest lucru in cadrul exemplului nostru, este util sa analizam o "schema" a aplicatiei:

Layout-uri in Qt

Precum se poate vedea, in layout-ul de tip QGridLayout (gridLayout), am adaugat cele doua label-uri (nameLabel, passwordLabel) si cele doua widget-uri de tip QLineEdit (m_userName, m_password).
In continuare, in layout-ul de tip QHBoxLayout (hLayout), am adaugat cele doua butoane (m_submit, m_clear).
Acest lucru asigura faptul ca butoanele vor ramane aliniate pe orizontala la redimensionarea ferestrei.
Apoi, am folosit un layout de tip QVBoxLayout (topLayout), in care am adaugat layout-ul de tip grid (gridLayout) si pe cel orizontal (hLayout).

  1.  
  2. connect(m_submit, SIGNAL(clicked()), this, SLOT(onSubmit()));
  3.  

Am conectat semnalul clicked() al butonului m_submit la slot-ul onSubmit()

  1.  
  2. connect(m_clear, SIGNAL(clicked()), this, SLOT(onClear()));
  3.  

Am conectat semnalul clicked() al butonului m_clear la slot-ul onClear().

  1.  
  2. void LineEdit::onSubmit()
  3.  

Slot apelat atunci cand utilizatorul apasa butonul m_submit.
Se face o verificare a datelor introduse (atat user-name-ul cat si parola trebuie introduse).
Apoi, daca datele au fost introduse, ele se afiseaza intr-un Message Box.

  1.  
  2. void LineEdit::onClear()
  3.  

Slot apelat atunci cand utilizatorul apasa butonul m_clear.
Se sterg datele introduse si se seteaza focus-ul pe widget-ul m_userName.

  1.  
  2. void LineEdit::keyPressEvent(QKeyEvent* event)
  3.  

Am redefinit functia keyPressEvent() pentru a trata doua situatii:
- utilizatorul apasa tasta ENTER
In acest caz, apelam slot-ul LineEdit::onSubmit() (adica aplicatia se comporta ca si cand utilizatorul ar fi apasat butonul m_submit)
-utilizatorul apasa tasta ESC
In acest caz incheiem executia aplicatiei
Functia LineEdit::keyPressEvent() va fi apelata de fiecare data cand utilizatorul va apasa o tasta, avand focus-ul pe fereastra aplicatiei.
Folosind event->key(), putem afla care din taste a fost apasata.

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include "lineedit.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     QApplication app(argc, argv);
  9.     LineEdit loginWidget;
  10.     loginWidget.setGeometry(400, 400, 200, 100);
  11.     loginWidget.setWindowTitle(QObject::tr("Login"));
  12.     loginWidget.show();
  13.     return app.exec();
  14. }
  15.  
  16.  


Se instaintiaza un obiect de tip LineEdit , se seteaza dimensiunile si pozitia pe ecran si se afiseaza.

QListWidget

QListWidget este folosit pentru a afisa informatii intr-un control de tip lista.
In exemplul de mai jos, afisam o lista continand nume de browsere. Cand utilizatorul selecteaza unul din elementele din lista, schimbam icon-ul elementului selectat si afisam numele sau intr-un label.

QListWidget in Qt

Sursele sunt urmatoarele:

  1.  
  2. // listwidget.h
  3. #ifndef LISTWIDGET_H
  4. #define LISTWIDGET_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QListWidget;
  9. class QListWidgetItem;
  10. class QLabel;
  11.  
  12. class ListWidget : public QWidget
  13. {
  14.     Q_OBJECT
  15.  
  16. public:
  17.     ListWidget(QWidget *parent = 0);
  18.     ~ListWidget();
  19.  
  20. public slots:
  21.     void currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous);
  22.  
  23. private:
  24.     QListWidget* m_listWidget;
  25.     QLabel* m_label;
  26. };
  27.  
  28. #endif // LISTWIDGET_H
  29.  


Clasa ListWidget, derivata din clasa QWidget, are doi membri:
- m_listWidget-> control-ul de tip lista
- m_label -> un control de tip label

Declaram slot-ul currentItemChanged(), care va fi apelat atunci cand elementul curent din lista se va schimba.

Implementare clasei ListWidget este urmatoarea:

  1.  
  2. // listwidget.cpp
  3. #include <QtGui/QListWidget>
  4. #include <QtGui/QListWidgetItem>
  5. #include <QtGui/QLabel>
  6. #include <QtGui/QVBoxLayout>
  7. #include <QtGui/QIcon>
  8.  
  9. #include "listwidget.h"
  10.  
  11. ListWidget::ListWidget(QWidget *parent)
  12.     : QWidget(parent)
  13. {
  14.     m_listWidget = new QListWidget;
  15.     m_listWidget->setSortingEnabled(true);
  16.     QListWidgetItem* item1 = new QListWidgetItem(QIcon(":/resources/images/unselected-icon.png"), tr("Internet Explorer"), m_listWidget);
  17.     QListWidgetItem* item2 = new QListWidgetItem(QIcon(":/resources/images/unselected-icon.png"),tr("Firefox"), m_listWidget);
  18.     QListWidgetItem* item3 = new QListWidgetItem(QIcon(":/resources/images/unselected-icon.png"),tr("Opera"), m_listWidget);
  19.  
  20.     // set the flags for the items in the list
  21.     item1->setFlags(item1->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled |
  22.                     Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable);
  23.     item2->setFlags(item1->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled |
  24.                     Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable);
  25.     item3->setFlags(item1->flags() | Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsDragEnabled |
  26.                     Qt::ItemIsDropEnabled | Qt::ItemIsUserCheckable);
  27.     connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this,
  28.             SLOT(currentItemChanged(QListWidgetItem*, QListWidgetItem*)));
  29.  
  30.     m_label = new QLabel;
  31.  
  32.     QVBoxLayout* layout = new QVBoxLayout;
  33.     layout->addWidget(m_listWidget);
  34.     layout->addWidget(m_label);
  35.  
  36.     setLayout(layout);
  37. }
  38.  
  39. ListWidget::~ListWidget()
  40. {
  41.  
  42. }
  43.  
  44. void ListWidget::currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous)
  45. {
  46.     current->setIcon(QIcon(":/resources/images/selected-icon.png"));
  47.     m_label->setText("<font color=\"red\"> <b>" + current->text() + "</font></b>");
  48.     if (previous)
  49.     {
  50.         previous->setIcon(QIcon(":/resources/images/unselected-icon.png"));
  51.     }
  52. }
  53.  


  1.  
  2. m_listWidget = new QListWidget;
  3. m_listWidget->setSortingEnabled(true);
  4.  

Cream widget-ul m_listWidget si specificam ca dorim ca elementele din lista sa fie sortate.

Elementele ce vor fi introduse intr-un widget QListWidget sunt de tipul QListWidgetItem

  1.  
  2. QListWidgetItem* item1 = new QListWidgetItem(QIcon(":/resources/images/unselected-icon.png"), tr("Internet Explorer"), m_listWidget);
  3. ...
  4.  

Cream elementele ce vor fi adaugata in lista. Se observa ca asociem si un icon elementelor.

  1.  
  2. connect(m_listWidget, SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)), this,
  3.             SLOT(currentItemChanged(QListWidgetItem*, QListWidgetItem*)));
  4.  

In momentul in care se schimba selectia in m_listWidget, este emis semnalul currentItemChanged.
Conectam acest semnal la slot-ul ListWidget::currentItemChanged()

  1.  
  2. void ListWidget::currentItemChanged(QListWidgetItem* current, QListWidgetItem* previous)
  3. {
  4. ...
  5. }
  6.  

current este element-ul curent (cel schimbat), previous este elementul precedent.
Schimbam icon-ul elementului curent si al celui precedent, astfel incat elementul curent (selectat) sa aiba un icon distinct fata de celelalte elemente (neselectate).

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include <QtGui/QIcon>
  5.  
  6. #include "listwidget.h"
  7.  
  8. int main(int argc, char *argv[])
  9. {
  10.     QApplication app(argc, argv);
  11.     ListWidget browsers;
  12.     browsers.setWindowTitle(QObject::tr("Favorite browser"));
  13.     browsers.setWindowIcon(QIcon(":/resources/images/app-icon.png"));
  14.     browsers.show();
  15.     return app.exec();
  16. }
  17.  


Se instantiaza un obiect de tip ListWidget , se seteaza titlul ferestrei, se seteaza un icon pentru fereastra si se afiseaza widget-ul.

Fisierul de resurse (resource.qrc) este urmatorul:

  1.  
  2. <RCC>
  3.     <qresource prefix="/resources">
  4.         <file>images/selected-icon.png</file>
  5.         <file>images/unselected-icon.png</file>
  6.         <file>images/app-icon.png</file>
  7.     </qresource>
  8. </RCC>
  9.  


QTreeWidget

QTreeWidget permite afisarea informatiei intr-un arbore
Elementele introduse in QTreeWidget sunt de tipul QTreeWidgetItem.

In exemplul urmator, vom arata cum se foloseste widget-ul QTreeWidget.

QTreeWidget in Qt

adauga in  QTreeWidget

redenumeste  QTreeWidgetItem

Pe langa utilizarea widget-ului QTreeWidget, acest exemplu va arata cum se lucreaza cu meniuri contextuale.

Codul este urmatorul:

  1.  
  2. // treewidget.h
  3. #ifndef TREEWIDGET_H
  4. #define TREEWIDGET_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QTreeWidget;
  9. class QTreeWidgetItem;
  10. class QLabel;
  11. class QContextMenuEvent;
  12. class QAction;
  13. class QMenu;
  14.  
  15. class TreeWidget : public QWidget
  16. {
  17.     Q_OBJECT
  18.  
  19. public:
  20.     TreeWidget(QWidget *parent = 0);
  21.     ~TreeWidget();
  22.     void setupActions();
  23.     void contextMenuEvent(QContextMenuEvent* contextEvent);
  24.  
  25. public slots:
  26.     void currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
  27.     void addChildItem();
  28.     void addTopLevelItem();
  29.     void removeSelected();
  30.     void renameSelected();
  31.  
  32. private:
  33.     QTreeWidget* m_treeWidget;
  34.     QLabel* m_label;
  35.     QMenu* m_menu;
  36.     QAction* m_addTopLevelAction;
  37.     QAction* m_addChildAction;
  38.     QAction* m_removeAction;
  39.     QAction* m_renameAction;
  40. };
  41.  
  42. #endif // TREEWIDGET_H
  43.  


Declaram clasa TreeWidget, care deriveaza din QWidget. Clasa contine urmatorii membri:
- m_treeWidget -> acesta este widget-ul de tip tree
- m_label -> acesta este un obiect de tip label, care va afisa numele elementului curent selectat
- m_addTopLevelAction -> o actiune ce va fi apelata din meniul contextual pentru a adauga un nou element top-level in arbore
- m_addChildAction -> o actiune ce va fi apelata din meniul contextual pentru a adauga un nou element ca si copil al elementului curent selectat
- m_removeAction -> o actiune ce va fi apelata din meniul contextual pentru a sterge elementul selectat
- m_renameAction -> o actiune ce va fi apelata din meniul contextual pentru a redenumi textul asociat elementului selectat

In clasa TreeWidget declaram urmatoarele slot-uri:
- currentItemChanged() -> apelat atunci cand se schimba elementul curent in arbore
- addChildItem() -> slot apelat ca rezult al activarii actiunii m_addChildAction
- addTopLevelItem() -> slot apelat ca rezult al activarii actiunii m_addTopLevelAction
- removeSelected() -> slot apelat ca rezult al activarii actiunii m_removeAction
- renameSelected() -> slot apelat ca rezult al activarii actiunii m_renameAction

Implementarea clasei se afla in fisierul treewidget.cpp.

Constructorul clasei este urmatorul:

  1.  
  2. // treewidget.cpp
  3. ...
  4. TreeWidget::TreeWidget(QWidget *parent)
  5.     : QWidget(parent)
  6. {
  7.     m_treeWidget = new QTreeWidget;
  8.     m_treeWidget->setColumnCount(1);
  9.  
  10.     QStringList columns;
  11.     columns << "Operating systems";
  12.     m_treeWidget->setHeaderLabels(columns);
  13.  
  14.     QStringList itemName;
  15.  
  16.     itemName << tr("Windows");
  17.     QTreeWidgetItem* windowsItem = new QTreeWidgetItem(itemName);
  18.     windowsItem->setIcon(0, QIcon(":/resources/images/windows.png"));
  19.     itemName.clear();
  20.  
  21.     itemName << tr("Windows XP");
  22.     new QTreeWidgetItem(windowsItem, itemName);
  23.     itemName.clear();
  24. ...
  25.     QList<QTreeWidgetItem*> osItems;
  26.     osItems << windowsItem << linuxItem << macItem;
  27.     m_treeWidget->addTopLevelItems(osItems);
  28.  
  29.     connect(m_treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
  30.             this, SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
  31.  
  32.     m_label = new QLabel;
  33.  
  34.     QVBoxLayout* layout = new QVBoxLayout;
  35.     layout->addWidget(m_treeWidget);
  36.     layout->addWidget(m_label);
  37.  
  38.     setLayout(layout);
  39.     setupActions();
  40. }
  41.  


In constructor, se efectueaza urmatoarele:
- se creeaza obiectul m_treeWidget, se specifica ca acesta foloseste o singura coloana si se seteaza numele coloanei
- se construiesc elementele arborelui, de tipul QTreeWidgetItem si se adauga in arbore. Elementele top-level se adauga folosind functia addTopLevelItems()
- se conecteaza semnalul currentItemChanged(), emis de catre m_treeWidget, la slot-ul currentItemChanged(), declarat in clasa TreeWidget
- se creaza obiectul m_label
- obiectele m_treeWidget si m_label se adauga intr-un layout de tip vertical, care se seteaza ca fiind layout-ul widget-ului nostru (TreeWidget)
- se apeleaza functia setupActions(), care se ocupa de crearea obiectelor actiune si cu asocierea lor la slot-urile corespunzatoare.

  1.  
  2. void TreeWidget::setupActions()
  3. {
  4.     m_menu = new QMenu(this);
  5.  
  6.     m_addTopLevelAction = new QAction(tr("Add top-level item"), this);
  7.     m_menu->addAction(m_addTopLevelAction);
  8.     connect(m_addTopLevelAction, SIGNAL(triggered()), this, SLOT(addTopLevelItem()));
  9.  
  10.     m_addChildAction = new QAction(tr("Add child item"), this);
  11.     m_menu->addAction(m_addChildAction);
  12.     connect(m_addChildAction, SIGNAL(triggered()), this, SLOT(addChildItem()));
  13.  
  14.     m_removeAction = new QAction(tr("Remove selected"), this);
  15.     m_menu->addAction(m_removeAction);
  16.     connect(m_removeAction, SIGNAL(triggered()), this, SLOT(removeSelected()));
  17.  
  18.     m_renameAction = new QAction(tr("Rename selected"), this);
  19.     m_menu->addAction(m_renameAction);
  20.     connect(m_renameAction, SIGNAL(triggered()), this, SLOT(renameSelected()));
  21. }
  22.  


In functia setupActions():
- se creeaza obiectul de tip meniu, folosit pentru meniul contextual (m_menu)
- se creeaza obiectele de tip actiune. Se asociaza semnalul triggered() al obiectelor de tip actiune la slot-urile corespunzatoare. Se adauga obiectele de tip actiune la meniu.

  1.  
  2. void TreeWidget::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
  3. {
  4.     if (current)
  5.         m_label->setText("<font color=\"blue\"> <b>" + current->text(0) + "</font></b>");
  6.     else
  7.         m_label->setText("");
  8. }
  9.  


Slot apelat atunci cand se selecteaza alt element in arbore.
Vom seta continutul label-ului m_label la numele noului element selectat.

  1.  
  2. void TreeWidget::addTopLevelItem()
  3. {
  4.     // open a dialog and prompt for a string
  5.     QString itemText = QInputDialog::getText(this, "Add new item",
  6.                  "Enter new item", QLineEdit::Normal);
  7.     if (!itemText.size())
  8.         return;
  9.  
  10.     QTreeWidgetItem* newItem = new QTreeWidgetItem;
  11.  
  12.     if (itemText == "Windows")
  13.         newItem->setIcon(0, QIcon(":/resources/images/windows.png"));
  14.     else if (itemText == "Linux")
  15.         newItem->setIcon(0, QIcon(":/resources/images/linux.png"));
  16.     else if (itemText == "Mac OS X")
  17.         newItem->setIcon(0, QIcon(":/resources/images/mac.png"));
  18.     else
  19.     {
  20.         QMessageBox::information(this, tr("Incorrect data entered"),
  21.                                  "Must choose between: Windows, Linux or Mac OS X");
  22.         return;
  23.     }
  24.  
  25.     newItem->setText(0, itemText);
  26.     QList<QTreeWidgetItem*> itemsToAdd;
  27.     itemsToAdd << newItem;
  28.     m_treeWidget->addTopLevelItems(itemsToAdd);
  29. }
  30.  


Slot apelat atunci cand utilizatorul exercita optiunea de a adauga un element top-level, din meniul contextual.

  1.  
  2. // open a dialog and prompt for a string
  3. QString itemText = QInputDialog::getText(this, "Add new item",
  4.                  "Enter new item", QLineEdit::Normal);
  5. if (!itemText.size())
  6.     return;
  7.  


Deschidem un dialog de tip QInputDialog, in care utlizatorul va introduce numele noului element.
Numele noului element trebuie sa fie unul din urmatoarele: Windows, Linux sau Mac OS X.

  1.  
  2. QTreeWidgetItem* newItem = new QTreeWidgetItem;
  3.  
  4. if (itemText == "Windows")
  5.     newItem->setIcon(0, QIcon(":/resources/images/windows.png"));
  6. else if (itemText == "Linux")
  7.     newItem->setIcon(0, QIcon(":/resources/images/linux.png"));
  8. else if (itemText == "Mac OS X")
  9.     newItem->setIcon(0, QIcon(":/resources/images/mac.png"));
  10. else
  11. {
  12.     QMessageBox::information(this, tr("Incorrect data entered"),
  13.                              "Must choose between: Windows, Linux or Mac OS X");
  14.     return;
  15. }
  16. newItem->setText(0, itemText);
  17. QList<QTreeWidgetItem*> itemsToAdd;
  18. itemsToAdd << newItem;
  19. m_treeWidget->addTopLevelItems(itemsToAdd);
  20.  


Se creeaza un nou element, de tipul QTreeWidgetItem, i se seteaza textul si icon-ul.
Se adauga noul element top-level in arbore, folosind functia addTopLevelItems().

  1.  
  2. void TreeWidget::addChildItem()
  3. {
  4.     QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
  5.     if (selectedItems.size() != 1)
  6.         return;
  7.  
  8.     // open a dialog and prompt for a string
  9.     QString itemText = QInputDialog::getText(this, "Add new item",
  10.                  "Enter new item", QLineEdit::Normal);
  11.     if (!itemText.size())
  12.         return;
  13.  
  14.     QTreeWidgetItem* newItem = new QTreeWidgetItem;
  15.     newItem->setText(0, itemText);
  16.     selectedItems[0]->addChild(newItem);
  17. }
  18.  


Slot-ul addChildItem() este apelat atunci cand utilizatorul doreste sa adauge un element ca si copil al elementului curent selectat.

  1.  
  2.  QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
  3.  if (selectedItems.size() != 1)
  4.      return;
  5.  


Preluam elementele selectate intr-o lista (de tip QList). Daca numarul de elemente selectate este diferit de 1, nu avem nimic de facut.

  1.  
  2. // open a dialog and prompt for a string
  3. QString itemText = QInputDialog::getText(this, "Add new item",
  4.              "Enter new item", QLineEdit::Normal);
  5. if (!itemText.size())
  6.     return;
  7.  


Deschidem un dialog in care utilizatorul poate introduce numele noului element.

  1.  
  2. QTreeWidgetItem* newItem = new QTreeWidgetItem;
  3. newItem->setText(0, itemText);
  4. selectedItems[0]->addChild(newItem);
  5.  


Se creeaza noul element, de tip QTreeWidgetItem. I se seteaza textul si se adauga in arbore ca si copil al elementului curent selectat, folosind functia addChild().

  1.  
  2. void TreeWidget::removeSelected()
  3. {
  4.     QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
  5.     if (selectedItems.size() != 1)
  6.         return;
  7.  
  8.     if (!selectedItems[0]->parent())
  9.     {
  10.         m_treeWidget->takeTopLevelItem(m_treeWidget->indexOfTopLevelItem(selectedItems[0]));
  11.     }
  12.     else
  13.     {
  14.         QTreeWidgetItem* parent = selectedItems[0]->parent();
  15.         parent->takeChild(parent->indexOfChild(selectedItems[0]));
  16.     }
  17. }
  18.  


Slot-ul removeSelected() este apelat atunci cand utilizatorul doreste sa stearga din arbore elementul curent selectat.

Sunt doua situatii:
1. Elementul pe care dorim sa il stergem nu are un parinte (este top-level). In cazul respectiv, elementul se sterge folosind functia takeTopLevelItem()
Functia primeste ca parametru index-ul elementului ce trebuie sters. Obtinem acest index folosind functia indexOfTopLevelItem()
2. Elementul pe care dorim sa il stergem are un parinte. In acest caz, elementul ca fi sters apeland functia indexOfChild() pe parinte.
Functia primeste ca parametru index-ul elementului ce trebuie sa fie sters. Obtinem acest index apeland functia indexOfChild() pe parinte.

  1.  
  2. void TreeWidget::renameSelected()
  3. {
  4.     QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
  5.     if (selectedItems.size() != 1)
  6.         return;
  7.  
  8.     // open a dialog and prompt for a string
  9.     QString newItemText = QInputDialog::getText(this, "Rename item",
  10.                  "Enter new item name", QLineEdit::Normal, selectedItems[0]->text(0));
  11.     if (!newItemText.size())
  12.         return;
  13.  
  14.     selectedItems[0]->setText(0, newItemText);
  15. }
  16.  


Slot-ul renameSelected() este apelat atunci cand utilizatorul doreste sa redenumeasca elementul curent selectat.

  1.  
  2. QList<QTreeWidgetItem *> selectedItems = m_treeWidget->selectedItems();
  3. if (selectedItems.size() != 1)
  4.     return;
  5.  


Se determina elementul curent selectat.

  1.  
  2. // open a dialog and prompt for a string
  3. QString newItemText = QInputDialog::getText(this, "Rename item",
  4.                  "Enter new item name", QLineEdit::Normal, selectedItems[0]->text(0));
  5. if (!newItemText.size())
  6.     return;
  7.  


Se deschide un dialog in care utilizatorul poate introduce noul nume al elementului.

  1.  
  2. selectedItems[0]->setText(0, newItemText);
  3.  


Se seteaza noul nume, folosind functia selectedItems()

  1.  
  2. void TreeWidget::contextMenuEvent(QContextMenuEvent* contextEvent)
  3. {
  4.     if (m_treeWidget->selectedItems().size() == 0)
  5.     {
  6.         m_removeAction->setDisabled(true);
  7.         m_addChildAction->setDisabled(true);
  8.         m_renameAction->setDisabled(true);
  9.     }
  10.     else
  11.     {
  12.         m_removeAction->setEnabled(true);
  13.         m_addChildAction->setEnabled(true);
  14.         m_renameAction->setEnabled(true);
  15.     }
  16.     m_menu->exec(contextEvent->globalPos());
  17. }
  18.  


Functia contextMenuEvent() se apeleaza in momentul in care utilizatorul apasa butonul drept al mouse-ului.
Daca nu avem nici un element selectat, lasam doar actiunea de adaugare a unui element top-level activa, celelalte fiind dezactivate.

  1.  
  2. m_menu->exec(contextEvent->globalPos());
  3.  


Afiseaza meniul contextual.

  1.  
  2. // main.cpp
  3. #include <QtGui/QApplication>
  4. #include "treewidget.h"
  5.  
  6. int main(int argc, char *argv[])
  7. {
  8.     QApplication a(argc, argv);
  9.     TreeWidget w;
  10.     w.show();
  11.     return a.exec();
  12. }
  13.  


Se creeaza un obiect de tipul TreeWidget si se afiseaza.

Fisierul de resurse (resource.qrc) este urmatorul:
  1.  
  2. <RCC>
  3.     <qresource prefix="/resources">
  4.         <file>images/linux.png</file>
  5.         <file>images/windows.png</file>
  6.         <file>images/mac.png</file>
  7.     </qresource>
  8. </RCC>
  9.  


QTextEdit

QTextEdit este un widget care permite afisarea si editarea de text.
De asemenea, permite afisarea de text HTML. Este a un candidat foarte bun pentru realizarea unui editor de text cu functionalitati minimale.

In exemplul urmator, afisam un text intr-un control de tip QTextEdit. Utilizatorul poate afisa textul in mod bold, italic sau underline, cu ajutorul unor butoane.

QTextEdit in Qt

Sursele sunt urmatoarele:

  1.  
  2. // textedit.h
  3. #ifndef TEXTEDIT_H
  4. #define TEXTEDIT_H
  5.  
  6. #include <QtGui/QWidget>
  7.  
  8. class QTextEdit;
  9. class QPushButton;
  10. class QTextCharFormat;
  11. class QTextCursor;
  12.  
  13. class TextEdit : public QWidget
  14. {
  15.     Q_OBJECT
  16.  
  17. public:
  18.     TextEdit(QWidget *parent = 0);
  19.     ~TextEdit();
  20.     void addInitialText();
  21.     QTextCursor getTextCursor();
  22.     void applyFormat(QTextCursor& cursor, const QTextCharFormat& textFormat);
  23.  
  24. public slots:
  25.     void bold();
  26.     void underline();
  27.     void italic();
  28.     void currentCharFormatChanged(const QTextCharFormat& format);
  29.  
  30. private:
  31.     QTextEdit* m_editor;
  32.     QPushButton* m_boldButton;
  33.     QPushButton* m_underlineButton;
  34.     QPushButton* m_italicButton;
  35. };
  36.  
  37. #endif // TEXTEDIT_H
  38.  


Declaram o noua clasa, TextEdit, derivata din QWidget.

Clasa are urmatorii membri:
- m_editor -> editorul propriu-zis
- m_boldButton -> dupa apasarea acestui buton, textul selectat va fi afisat in format [ibold[/i]
- m_underlineButton -> dupa apasarea acestui buton, textul selectat va fi afisat in format underline
- m_italicButton -> dupa apasarea acestui buton, textul selectat va fi afisat in format italic

Declaram si urmatoarele slot-uri:
- bold() -> slot apelat in momentul in care este apasat butonul m_boldButton
- underline() -> slot apelat in momentul in care este apasat butonul m_underlineButton
- italic() -> slot apelat in momentul in care este apasat butonul m_italicButton
- currentCharFormatChanged() -> slot apelat in momentul in care formatul caracterului curent, din editor, s-a schimbat

Implementarea clasei TextEdit este urmatoarea:

  1.  
  2. // textedit.cpp
  3. #include <QtGui/QTextEdit>
  4. #include <QtGui/QPushButton>
  5. #include <QtGui/QVBoxLayout>
  6. #include <QtGui/QHBoxLayout>
  7. #include <QtGui/QTextCharFormat>
  8. #include <QtGui/QTextCursor>
  9.  
  10. #include "textedit.h"
  11.  
  12. TextEdit::TextEdit(QWidget *parent)
  13.     : QWidget(parent)
  14. {
  15.     m_editor = new QTextEdit;
  16.     connect(m_editor, SIGNAL(currentCharFormatChanged(QTextCharFormat)), this,
  17.             SLOT(currentCharFormatChanged(QTextCharFormat)));
  18.  
  19.     m_boldButton = new QPushButton;
  20.     m_boldButton->setText(tr("Bold"));
  21.     m_boldButton->setCheckable(true);
  22.     connect(m_boldButton, SIGNAL(clicked()), this, SLOT(bold()));
  23.  
  24.     m_underlineButton = new QPushButton;
  25.     m_underlineButton->setText(tr("Underline"));
  26.     m_underlineButton->setCheckable(true);
  27.     connect(m_underlineButton, SIGNAL(clicked()), this, SLOT(underline()));
  28.  
  29.     m_italicButton = new QPushButton;
  30.     m_italicButton->setText(tr("Italic"));
  31.     m_italicButton->setCheckable(true);
  32.     connect(m_italicButton, SIGNAL(clicked()), this, SLOT(italic()));
  33.  
  34.     QHBoxLayout* hLayout = new QHBoxLayout;
  35.     hLayout->addWidget(m_boldButton);
  36.     hLayout->addWidget(m_underlineButton);
  37.     hLayout->addWidget(m_italicButton);
  38.  
  39.     QVBoxLayout* vLayout = new QVBoxLayout;
  40.     vLayout->addWidget(m_editor);
  41.     vLayout->addLayout(hLayout);
  42.     setLayout(vLayout);
  43.  
  44.     addInitialText();
  45. }
  46.  
  47. TextEdit::~TextEdit()
  48. {
  49.  
  50. }
  51.  
  52. void TextEdit::addInitialText()
  53. {
  54.     QString text = "Lorem ipsum dolor sit amet, consectetur adipisicing elit sed ";
  55.     text += "do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
  56.     m_editor->insertPlainText(text);
  57. }
  58.  
  59. QTextCursor TextEdit::getTextCursor()
  60. {
  61.     QTextCursor cursor = m_editor->textCursor();
  62.  
  63.     if (!cursor.hasSelection())
  64.         cursor.select(QTextCursor::WordUnderCursor);
  65.  
  66.     return cursor;
  67. }
  68.  
  69. void TextEdit::applyFormat(QTextCursor& cursor, const QTextCharFormat& textFormat)
  70. {
  71.     cursor.mergeCharFormat(textFormat);
  72.     m_editor->mergeCurrentCharFormat(textFormat);
  73. }
  74.  
  75. void TextEdit::bold()
  76. {
  77.     QTextCursor cursor = getTextCursor();
  78.     QTextCharFormat textFormat;
  79.     textFormat.setFontWeight(m_boldButton->isChecked() ? QFont::Bold : QFont::Normal);
  80.     applyFormat(cursor, textFormat);
  81. }
  82.  
  83. void TextEdit::underline()
  84. {
  85.     QTextCursor cursor = getTextCursor();
  86.     QTextCharFormat textFormat;
  87.     textFormat.setFontUnderline(m_underlineButton->isChecked());
  88.     applyFormat(cursor, textFormat);
  89. }
  90.  
  91. void TextEdit::italic()
  92. {
  93.     QTextCursor cursor = getTextCursor();
  94.     QTextCharFormat textFormat;
  95.     textFormat.setFontItalic(m_italicButton->isChecked());
  96.     applyFormat(cursor, textFormat);
  97. }
  98.  
  99. void TextEdit::currentCharFormatChanged(const QTextCharFormat& format)
  100. {
  101.     m_boldButton->setChecked(format.font().bold());
  102.     m_italicButton->setChecked(format.font().italic());
  103.     m_underlineButton->setChecked(format.font().underline());
  104. }
  105.  

6.67 points / 3 votes
... write a test, make it fail, write code, pass the test, refactor, run again, write a test, ... and so on ...
User avatar
morpheus
Word
 
Joined: 30 Dec 2009
Points: 33.34

Return to Tutoriale QT

Who is online

Users browsing this forum: No registered users and 0 guests