1   2   3   4
Ім'я файлу: Основний розділ.doc
Розширення: doc
Розмір: 1193кб.
Дата: 04.03.2020
скачати

Робота з таблицями баз даних

Найпростіший спосіб відображення інформації бази даних у вигляді таблиці полягає у використанні класів Qsqlquerymodel і Qtableview:

Qsqlquerymodel model;

model.setquery("select * from employee");
Qtableview view;

view.setmodel(&model);

view.show();

Але замість Qsqlquerymodel будемо використовувати клас Qsqltablemodel, що дозволяє працювати з таблицями баз даних на більш високому рівні, чим виконання Sql-Запитів. Тоді наведений вище фрагмент коду запишеться в такий спосіб:

Qsqltablemodel model;

model.settable("employee");

model.select();
Qtableview view;

view.setmodel(&model);

view.show();

Більш складний приклад: замість виконання Sql-Запиту

SELECT * FROM employee WHERE salary >= 1000 ORDER BY id DESC

для моделі Qsqltablemodel треба задати фільтр і умову сортування:

Qsqltablemodel model = Qsqltablemodel(parent, db);

model.settable("employee"); // Ім'я таблиці бази даних.

model.setfilter("salary >= 1000"); // Умова WHERE.

model.setsort(0, Qt::Descendingorder); // Сортування по убуванню id.

model.select(); // Одержати дані.

Після визначення моделі можна довідатися значення кожного поля будь-якого запису, наприклад:

Qstring name = model.record(i).value("name").tostring();

або

int salary = model.data(model.index(i, 3)).toint();

Для перебору всіх записів набору даних:

for (int i = 0; i < model.rowcount(); ++i)

{

Qsqlrecord record = model.record(i);

Qstring name = record.value("name").tostring();

double salary = record.value("salary").todouble();

.......

}

У лістингу наведений програмний код для роботи з таблицею.

Лістинг. Таблиця бази даних

1// Таблиця бази даних

2

3 #include

4 #include

5

6 int main(int argc, char *argv[]) {

7

8 Qapplication app(argc, argv);

9

10 Qtextcodec *codec = Qtextcodec::codecforname("CP1251");

11 Qtextcodec::setcodecfortr(codec);

12 Qtextcodec::setcodecforcstrings(codec);

13 Qtextcodec::setcodecforlocale(codec);

14

15 Qsqldatabase db = Qsqldatabase::adddatabase("QODBC");

16 db.setdatabasename("mysql_db1");

17 db.setusername("");

18 db.setpassword("");

19 db.open();

20

21// Qsqlquery q;

22// Для коректного відображення символів кирилиці:

23

24// q.exec(Qobject::tr("SET NAMES 'cp1251'"));

25

26 Qsqltablemodel *model = new Qsqltablemodel();

27 model->settable("employee");

28

29 model->insertrows(0, 1);

30 model->setdata(model->index(0, 0), 159);

31 model->setdata(model->index(0, 1), Qobject::tr("Сова"));

32 model->setdata(model->index(0, 2), Qdate(1985, 12, 31));

33 model->setdata(model->index(0, 3), 12.34);

34 model->setdata(model->index(0, 4), 1);

35 model->submitall();

36

37 model->seteditstrategy(Qsqltablemodel::Onfieldchange);

38

39 model->select();

40 model->setheaderdata(0, Qt::Horizontal,

41 Qobject::tr("Номер"));

42 model->setheaderdata(1, Qt::Horizontal,

43 Qobject::tr("Ім'я"));

44 model->setheaderdata(2, Qt::Horizontal,

45 Qobject::tr("День народження"));

46 model->setheaderdata(3, Qt::Horizontal,

47 Qobject::tr("Зарплата"));

48 model->setheaderdata(4, Qt::Horizontal,

49 Qobject::tr("Одружений"));

50

51 Qtableview *view = new Qtableview();

52 view->setmodel(model);

53

54 view->setalternatingrowcolors(true);

55 view->resizerowstocontents();

56 view->resizecolumnstocontents();

57 view->show();

58

59 return app.exec();

60 }

Тепер можна змінювати дані в клітинках, при редагуванні чисел і дат автоматично відображаються кнопки інкременту/декременту. Але оскільки для елемента Qdoublespinbox за замовчуванням задане максимальне значення 99.99. Зрозуміло, спроба ввести число більше припустимого, кінчається невдачею. Крім того, після редагування першої ж клітинки таблиці, коли відбувається автоматичне поновлення даних, ширина стовпців і висота рядків змінюється, тому що розміри клітинок за замовчуванням відрізняються від тих, що встановилися в результаті однократного виконання методів resizerowstocontents і resizecolumnstocontents.

Якщо ми прагнемо вносити різноманітні дані, виводити різні стовпці різним кольором, відображати галочки для полів логічного типу, використовувати календарик для введення дат, загалом, якось змінювати задані за замовчуванням параметри відображення й редагування клітинок, то в нас є дві можливості: розробляти свій клас моделі і вигляду таблиці або використовувати спеціальні об'єкти-делегати для її клітинок.
Розробка моделі й вигляду таблиці БД

У клітинках останнього стовпця таблиці, де зберігається тільки два можливі значення, будемо відображати елемент Qcheckbox і текст "Так" або "Ні". Крім того, заборонимо редагування першого стовпця, змінимо колір клітинок першого й останнього стовпців, а також параметри шрифту в другому стовпці.

Для цього створимо свою модель таблиці, використавши в якості базового клас QSqlQueryModel. А щоб управляти розмірами гнізд таблиці, визначимо свій клас представлення таблиці на основі стандартного Qtableview. Нижче наведений текст програми.

Лістинг. Модель і вигляд таблиці БД

1 #include

2 #include

3

4 class Mymodel : public Qsqlquerymodel {

5 Q_OBJECT

6 public:

7 Mymodel(Qobject *parent = 0);

8 Qt::Itemflags flags(const Qmodelindex &index) const;

9 Qvariant data(const Qmodelindex &index,

10 int role = Qt::Displayrole) const;

11 bool setdata(const Qmodelindex &index,

12 const Qvariant &value, int role);

13 private:

14 void refresh();

15 };

16

17 class Myview : public Qtableview {

18 Q_OBJECT

19 public:

20 Myview(Qwidget *parent = 0);

21 private:

22 virtual void resizeevent(Qresizeevent *event);

23 };

Лістинг. Модель і представлення таблиці БД

1// Таблиця бази даних: користувацька модель і представлення

2

3 #include

4 #include

5

6 #include "db02.h"

7

8 Mymodel::Mymodel(Qobject *parent)

9  : Qsqlquerymodel(parent) {

10 refresh();

11 }

12

13 Qt::Itemflags Mymodel::flags(

14 const Qmodelindex &index) const {

15

16 Qt::Itemflags flags = Qsqlquerymodel::flags(index);

17 if (index.column() >= 1 && index.column() < 4)

18 flags |= Qt::Itemiseditable;

19 if (index.column() == 4)

20 flags |= Qt::Itemisusercheckable;

21 return flags;

22 }

23

24 Qvariant Mymodel::data(

25 const Qmodelindex &index,

26 int role) const {

27

28 Qvariant value = Qsqlquerymodel::data(index, role);

29

30 switch (role) {

31

32 case Qt::Displayrole: // Дані для відображення

33 case Qt::Editrole: // Дані для редагування

34 if (index.column() == 0)

35 return value.tostring().prepend(tr("№"));

36 else if (index.column() == 2 && role == Qt::Displayrole)

37 return value.todate().tostring("dd.MM.yyyy");

38 else if (index.column() == 3 && role == Qt::Displayrole)

39 return tr("%1")

40.arg(value.todouble(), 0, 'f', 2);

41 else if (index.column() == 4)

42 return value.toint() != 0 ? tr("Так") : tr("Ні");

43 else

44 return value;

45

46 case Qt::Textcolorrole: // Колір тексту

47 if(index.column() == 1)

48 return qvariantfromvalue(Qcolor(Qt::blue));

49 else

50 return value;

51

52 case Qt::Textalignmentrole: // Вирівнювання

53 if(index.column() == 3)

54 return int(Qt::Alignright | Qt::Alignvcenter);

55 else if(index.column() == 2 || index.column() == 4)

56 return int(Qt::Alignhcenter | Qt::Alignvcenter);

57 else

58 return int(Qt::Alignleft | Qt::Alignvcenter);

59

60 case Qt::Fontrole: // Шрифт

61 if(index.column() == 1) {

62 Qfont font = Qfont("Helvetica", 10, Qfont::Bold);

63 return qvariantfromvalue(font);

64 }else

65 return value;

66

67 case Qt::Backgroundcolorrole: { // Колір

68 int a = (index.row() % 2) ? 14 : 0;

69 if(index.column() == 0)

70 return qvariantfromvalue(Qcolor(220,240-a,230-a));

71 else if(index.column() == 4)

72 return qvariantfromvalue(Qcolor(200,220-a,255-a));

73 else

74 return value;

75 }

76 case Qt::Checkstaterole: // Галочка

77 if (index.column() == 4)

78 return (Qsqlquerymodel::data(index).toint() != 0) ?

79 Qt::Checked : Qt::Unchecked;

80 else

81 return value;

82

83 case Qt::Sizehintrole: // Розмір клітинки

84 if (index.column() == 0)

85 return Qsize(70, 10);

86 if (index.column() == 4)

87 return Qsize(60, 10);

88 else

89 return Qsize(110, 10);

90 }

91 return value;

92 }

93

94 bool Mymodel::setdata(

95 const Qmodelindex &index,

96 const Qvariant &value,

97 int /* role */) {

98 if (index.column() < 1 || index.column() > 4)

99 return false;

100

101 Qmodelindex primarykeyindex = Qsqlquerymodel::index(

102 index.row(), 0);

103 int id = Qsqlquerymodel::data(primarykeyindex).toint();

104

105//clear(); // Якщо треба повністю перемалювати таблицю.

106

107 bool ok;

108 Qsqlquery query;

109 if (index.column() == 1) {

110 query.prepare("update employee set name = ? where id = ?");

111 query.addbindvalue(value.tostring());

112 query.addbindvalue(id);

113 }else if(index.column() == 2) {

114 query.prepare("update employee set born = ? where id = ?");

115 query.addbindvalue(value.todate());

116 query.addbindvalue(id);

117 }else if(index.column() == 3) {

118 query.prepare("update employee set salary = ? where id = ?");

119 query.addbindvalue(value.todouble());

120 query.addbindvalue(id);

121 }else if(index.column() == 4) {

122 query.prepare("update employee set married = ? where id = ?");

123 query.addbindvalue(value.tobool());

124 query.addbindvalue(id);

125 }

126 ok = query.exec();

127 refresh();

128 return ok;

129 }

130

131 void Mymodel::refresh() {

132 setquery("select * from employee ORDER BY id");

133

134 setheaderdata(0, Qt::Horizontal, tr("Номер"));

136 setheaderdata(1, Qt::Horizontal, tr("Ім'я"));

138 setheaderdata(2, Qt::Horizontal, tr("День народження"));

140 setheaderdata(3, Qt::Horizontal, tr("Адреса"));

142 setheaderdata(4, Qt::Horizontal, tr("Одружений/\n"));

144 }

145

146//------------------------------------

147 Myview::Myview(Qwidget *parent)

148  : Qtableview(parent) {

149

150 }

151

152 void Myview::resizeevent(Qresizeevent *event) {

153 resizerowstocontents();

154 resizecolumnstocontents();

155 Qtableview::resizeevent(event);

156 }

157

158//------------------------------------

159 int main(int argc, char *argv[]) {

160

161 Qapplication app(argc, argv);

162

163 Qtextcodec *codec = Qtextcodec::codecforname("CP1251");

164 Qtextcodec::setcodecfortr(codec);

165 Qtextcodec::setcodecforcstrings(codec);

166

167 Qsqldatabase db = Qsqldatabase::adddatabase("QMYSQL");

168 db.setdatabasename("db1");

169 db.setusername("root");

170 db.setpassword("password");

171 db.open();

172

173// Qsqlquery q;

174// Для коректного відображення кирилиці, можливо,

175// прийде встановити кодування:

176//q.exec(Qobject::tr("SET NAMES 'cp1251'"));

177

178 Mymodel *model = new Mymodel();

179

180 Myview *view = new Myview();

181 view->setmodel(model);

182

183 view->setalternatingrowcolors(true);

184 view->resizerowstocontents();

185 view->resizecolumnstocontents();

186 view->show();

187

188 return app.exec();

189 }

Для своєї моделі ми використовували базовий клас Qsqlquerymodel, що працює з довільним набором Sql-Запитів для читання й запису даних у БД. Але так нам потрібно докладно розписувати реалізацію методів data і setdata. У цьому випадку ми мали справу з єдиною таблицею бази даних, тому можна було в якості базового класу брати клас Qsqltablemodel.

1.7. Тестування та налагодження ПЗ



Рисунок 11. Список автомобілів організації



Рисунок 12. Таблиця зі списком шоферів



Рисунок 13. Дані про операторів диспетчерської служби.


1   2   3   4

скачати

© Усі права захищені
написати до нас