© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB
23 июля 2018 г. 9:04
Arrow

QComboBox делегат для QTableView

Добрый день!
Подскажите пожалуйста как можно реализовать делегат в виде QComboBox для ячейки в QTableView.
Данные в сам QComboBox будут браться с отдельной таблицы в базе данных и id выбранной записи необходимо записать в основную таблицу.
Искал в сети пример, но везде реализуют только делегат с уже внесенными данными в конструкторе самого делегата.

Пробовал так:

#ifndef COMBODELEGATE_H
#define COMBODELEGATE_H

#include <QItemDelegate>
#include <QComboBox>

class QModelIndex;
class QWidget;
class QVariant;

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

QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

#endif // COMBODELEGATE_H
Реализация:
#include "combodelegate.h"

#include <QWidget>
#include <QModelIndex>
#include <QAbstractItemModel>

ComboBoxDelegate::ComboBoxDelegate(QObject *parent)
:QItemDelegate(parent)
{

}

QWidget *ComboBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex &/* index */) const
{
QComboBox* editor = new QComboBox(parent);
return editor;
}

void ComboBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox *comboBox = dynamic_cast<QComboBox*>(editor);
int value = index.data(Qt::EditRole).toInt();
comboBox->setCurrentIndex(value);
}

Делегат отображается в ячейке, так, но пустой:
ui->mainTableView->setItemDelegateForColumn(2, new ComboBoxDelegate(this));

Как в него запихнуть модель с данными и затем получать id выбранной записи не пойму.
21 июля 2018 г. 17:25
Arrow

Получение прав пользователей на таблицу базы данных

Добрый день!
Возник вопрос: Как можно получить права пользователя на таблицу базы данных в Qt?
База данных PostgreSQL.
У меня в базе на сервере пользователи:
1. Несколько с правами:  SELECT, UPDATE, DELETE, INSERT (просмотр, редактирование, создание и удаление записей) - для примера user
2. Несколько с правами: INSERT (только запись, без просмотра - организована отдельная форма в программе) - им просматривать данные запрещено в целях безопасности - для примера editor.
3. Несколько с правами: SELECT (только чтение) - для примера guest.
Права давал так:

GRANT SELECT, INSERT, UPDATE, DELETE ON main_table to "user"
GRANT SELECT ON main_table to "guest"
GRANT INSERT ON main_table to "editor"
В программе хочу сделать фильтрацию по правам пользователя и в зависимости от них показывать свое окно для каждого из пользователей.
У admin и guest окно с таблицей (отображение через QQsqlRelationTableModel и QTableView). У guest отключена возможность редактирования данных в ячейках таблицы и скрыти кнопки добавления, редактирования и удаления записей.
У editor - отдельное окно с QLineEdit, QComboBox и QToolButton - он видит только то что сейчас вносит.
Уже выполнил:
ALTER TABLE main_table DISABLE ROW LEVEL SECURITY
так что данные отображаются в программе корректно.

Как возможно такое реализовать средствами Qt или SQL?

18 июля 2018 г. 11:20
Arrow

Разделение интерфейса и логики приложения

Добрый день!
Возник такой интересный вопрос: хочется в программе, которая использует базы данных полностью или по максимуму разделить интерфейс и логику работы с самой базой данных.
С таблицами, выборками и поиском все ясно, их необходимо с использования QTableModel, QRelationTableModel и т.д. перевести на QSqlquery.
Вопрос в том как быть с полями редактирования данных (QLineEdit, QTextEdit и др.)?
Работа с ними организована при помощи QDataWidgetMapper. Выполнять запрос Sql и потом из него вытягивать результаты и раскидывать по нужным полям (по очереди в цикле) или есть другой вариант.
И как быть с тем, что таблиц много и писать под каждую свой запрос не очень то и хочется (это только для отображения данных в таблице, а еще и редактирование данных / отдельная форма с QLineEdit, QTextEdit и др. под каждую таблицу/ ).
Больше хочется сделать, что-то универсальное, чтобы не пришлось в классах форм писать что-то типа:
MyClass *class = new MyClass();
class.sql("SELECT ... FROM ...");

то-есть описывать сам запрос в классе формы.
Как можно поступить в данной ситуации?


17 июля 2018 г. 7:52
Евгений Сальников

Одновременная работа с базой данных

Доброго времени суток!

Необходимо написать приложение в котором будут одновременно работать с большой таблицей из MySql. Нужно чтобы работа была в режиме онлайн, если один что то изменил у остальных это должно отобразиться. С базой данных в Qt работать я умею, проблема в том что я не знаю как организовать онлайн работу. Я ни как не могу найти информацию о том как это сделать и что нужно использовать. Подскажите что нужно изучить и в какую сторону смотреть, чтобы суметь реализовать данный момент.

12 июля 2018 г. 6:55
Владимир Соболев

OpenSSL на Windows10

Добрый день .. Ни как не могу завести  openSSl под 10 виндой.

Под 7 и 8 все работает хорошо .. Пробую запустить под 10й . (Ошибка  QSslSocket: cannot call unresolved function SSLv23_client_method).
Файлы  libeay32.dll и  ssleay32.dll скопировал в корень с программой.. Версии OpenSSl  пробовал разные  и OpenSSL v1.0.2o и OpenSSL v1.1.0h .



9 июля 2018 г. 10:14

QtQt/C++ - Урок 082. Кастомные виджеты в графическом дизайнере Qt Designer

QtDesigner, Widget, Qt

Периодически возникают вопросы связанные с наследованием виджетов и применении наследованных виджетов в рамках графического дизайнера Qt Designer.

Если применение виджета в рамках кода в целом является понятным, то как прикрутить кастомный виджет к ui форме на первый взгляд не понятно.

Давайте посмотрим на примере наследованной кнопки QPushButton.

5 июля 2018 г. 13:45
Arrow

Хранение выбранного цвета в базе данных

Добрый день!

Помогите пожалуйста со следующим вопросом: В программе хочу реализовать выбор цвета с его записью в базу данных. Подскажите какой тип должно иметь поле в базе данных для хранения цвета.
Как лучше организовать выбор цвета:
1. Список цветов хранится в отдельной таблице в базе данных и оттуда загружается в QComboBox, затем индекс выбранного записывается в поле в основной таблице.  / Сомневаюсь, что это хорошее решение /
2. Реализовать выбора цвета при помощи QColorDialog (нажатие на кнопку открывает диалог; выбранный цвет устанавливается в качестве цвета фона кнопки (или строки QLineEdit), а значение (#RRGGBB) в качестве текста). Потом в базу данных записывать значение цвета / считывать значение цвета и устанавливать на кнопку (QColorDialog при открытии инициализируется этим цветом). / Похоже самое верное решение /

3. Реализовать что-то похожее на изображенное на картинке. / Не знаю как такое сделать /

Как потом считать это значение?
Пробовал считать значение цвета (записано в ручную) в качестве #RRGGBB из ячейки с типом text.

Пытался так:

QSqlQuery query;
query.prepare("SELECT colour_name FROM table");
query.exec();
while (query.next()) {
        QColor color = QColor(query.value(index).toString());
        /* * * * * */
}

Но цвет не распознается - отображается как #000000 (какое бы значение цвета не записывал.
2 июля 2018 г. 18:24

QtQt/C++ - Урок 81. Как сделать базовый класс для виджетов использующих ui файлы форм

Qt, ui, Form, C++

В некоторых случаях может потребоваться создавать классы форм виджетов, у которых будет кастомный базовый класс. То есть класс формы виджета будет наследован от вашего класса, а не напрямую от QWidget , QDialog или QMainWindow .

Естественно, что для этого ваш кастомный класс должен быть наследован от одного из этих трёх классов. Но при этом у вас будет собственный базовый класс для какого-либо специфичного функционала, не важно для какого. Не будем делать Холивар о том, насколько удобно или неудобно использовать Qt Designer или лучше писать всё вручную в коде. Знаю, что у некоторые программисты не приемлют использование Qt Designer. Но остановимся на том, что для меня он удобен, как и для части других программистов.

Создадим два класса форм FirstForm и SecondForm , которые будут наследованы от виджета BaseWidget , который в свою очередь наследован от QWidget .

Внешний вид окна приложения будет таким.

2 июля 2018 г. 12:04
Arrow

Рефакторинг кода

Добрый день!

Подскажите, пожалуйста, как можно в ниже приведенном случае уменьшить количество практически одинакового повторяющегося кода.
Смотрел в сторону шаблонов проектирования или возможно это можно сделать по другому, а может просто я намудрил. Не могу определиться какое решение в этом случае будет правильным.

Есть несколько форм, которые отображаются в главном окне методом setCentralWidget() в зависимости от выбранного пользователем пункта меню (элементы управления на всех разные).

Изначально на главной форме отображается главное представление ( setCentralWidget() ) с разными данными ( таблица ), при нажатии кнопки создать отображается новая форма в зависимости от данных отображаемых в таблице.

Код функции:

void MainWindow::createView(TableForm::Type type, int rowIndex, int id)
{
    switch (type) {
    case TableForm::users:
        userForm = new CreateUserForm(this);
        setCentralWidget(userForm);
        delete mainForm;
        this->prewView = userForm;

        if (rowIndex > -1) {
            userForm->setRowIndex(rowIndex);
        }

        connect(userForm, &CreateUserForm::sygnalBack, this, [this, type]() { setMainView(type); });
        connect(userForm, &CreateUserForm::sygnalSubmit, this, [this, type]() { setMainView(type); });
        break;
    case TableForm::logo:
        logoForm = new CreateLogoForm(this);
        setCentralWidget(logoForm);
        delete mainForm;
        this->prewView = logoForm;
		
		if (rowIndex > -1) {
            userForm->setRowIndex(rowIndex);
        }

        connect(logoForm, &CreateLogoForm::sygnalBack, this, [this, type]() { setMainView(type); });
        connect(logoForm, &CreateLogoForm::sygnalSubmit, this, [this, type]() { setMainView(type); });
        break;
     case

/*  ******  Дальше похожий код  ******  */

    default:
        break;
    }
}


***********

enum Type {
none = 0,
users,
logo,
/* и т.д. */
};

***************

// Форма основного представления

connect(mainForm, &TableForm::createData, this, &MainWindow::createView);


// Главная форма

connect(ui->createButton, &QToolButton::clicked, this, [this] {
emit createData(this->viewType); // Create new data
});


// Объявления в разных формах
void createData(Type type, int row=-1, int id=-1);

void createView(TableForm::Type type, int rowIndex, int id);

24 июня 2018 г. 14:10
Arrow

QComboBox и База данных

Добрый день.

Необходима помощь в работе с QComboBox в связке с базой данных.

Описание:

Есть две таблицы:

1) "extension" с полями: id, library, function, ext.
2) "ext_type" с полями: id, type.

Таблицы связаны по полям ext и type. В первую таблицу в поле ext записывается id из второй таблицы.

В главном окне расположена таблица в которой отображаются данные из таблицы extension, в поле ext  подставляется вместо id соответствующий type из таблицы "ext_type".

Код:


mainModel = new QSqlRelationalTableModel(this);
mainModel->setTable("extension");

mainModel->setSort(0, Qt::AscendingOrder);
ui->mainTableView->setModel(mainModel);

// Выбор extension с таблицы ext_type по id
mainModel->setRelation(3, QSqlRelation("ext_type", "id", "type"));
ui->mainTableView->setItemDelegate(new QSqlRelationalDelegate(ui->mainTableView));
mainModel->select();

ui->mainTableView->setColumnHidden(0, true);

for (int i = 0; i < ui->mainTableView->horizontalHeader()->count(); i++) {
 ui->mainTableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
}
Все подставляется хорошо.

Второе окно открывается при редактировании записи в таблице или создании новой. На нем расположены QLineEdit для полей library, function и QComboBox для поля extension.

Нужно чтобы при создании новой записи из QComboBox пользователь мог выбрать значения из поля type таблицы ext_type.


Сделал так (под выбор работает а при редактировании существующей записи в QComboBox появляется не та строка):

ОШИБКА ЗДЕСЬ:

model = new QSqlTableModel(this);

mapper = new QDataWidgetMapper();
mapper->setModel(model);

mapper->addMapping(ui->Line1, 1);
mapper->addMapping(ui->Line2, 2);

QSqlQueryModel *select = new QSqlQueryModel(this);
select->setQuery("select type from ext_type");
ui->comboBox->setModel(select);

mapper->addMapping(ui->comboBox, model->fieldIndex("extension"), "currentIndex");

mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);

mapper->toLast();
Сохранение так (сохраняет, но из comboBox в таблицу попадает не та запись (см. выше)):

mapper->submit();
model->submitAll();

model->select();
mapper->toLast();
Помогите решить проблему.

И почему-то
mainModel->setRelation(3, QSqlRelation("ext_type", "id", "type"));
с таблицами выше работает.

А в этом случае нет:

mainModel = new QSqlRelationalTableModel(this);
mainModel->setTable("security_question");

mainModel->setSort(0, Qt::AscendingOrder);
ui->mainTableView->setModel(mainModel);

// Здесь
mainModel->setRelation(1, QSqlRelation("question", "id", "type"));
ui->mainTableView->setItemDelegate(new QSqlRelationalDelegate(ui->mainTableView));
mainModel->select();

ui->mainTableView->setColumnHidden(0, true);

for (int i = 0; i < ui->mainTableView->horizontalHeader()->count(); i++) {
ui->mainTableView->horizontalHeader()->setSectionResizeMode(i, QHeaderView::Stretch);
}
В таблицу на форме  вообще не выводятся данные (в сама таблица в базе данных заполнена).

Структура таблиц:
1) Таблица security_question: id, SecurityQuestion, Answer.
2) Таблица question: id, type.

Что может быль не так?

И подскажите как возможно организовать в базе данных запись в поле таблицы типа result1 или result2 в зависимости от того, какой QRadioButton пользователь выбрал на форме. А также, чтобы при редактировании данных на форме включался нужный QRadioButton в зависимости от записи?

В этом случае пока ничего не придумал.

Заранее спасибо за ответ и извините за долгое и возможно немного не понятное описание вопроса.
























22 июля 2018 г. 20:56
Тарас

C++ - Тест 001. Первая программа и типы данных

  • Результат 73баллов,
  • Очки рейтинга1
22 июля 2018 г. 18:29
Kaptn

C++ - Тест 003. Условия и циклы

  • Результат 100баллов,
  • Очки рейтинга10
22 июля 2018 г. 7:48
Kaptn

C++ - Тест 003. Условия и циклы

  • Результат 64баллов,
  • Очки рейтинга-1
Последние комментарии
18 июля 2018 г. 12:45
plgrm44

Qt/C++ - Урок 050. Логирование событий Qt приложения в текстовый файл

А что мешает сохранить адрес дефолтного обработчика и после вывода в файл вызывать и его?
17 июля 2018 г. 13:34
Arrow

Qt/C++ - Урок 049. QTranslator - динамический перевод мультиязычного приложения на Qt

Работает так: find_package (Qt5LinguistTools)file (GLOB TS_FILES ${SOURCE_DIR}/translations/*.ts)qt5_add_translation (QM_FILES ${TS_FILES})add_custom_target (translations ALL DEPE...
17 июля 2018 г. 9:53
Илья Чичак

Django - Урок 035. Различные шаблоны для рендеринга разных типов контента в поисковой выдаче

тут все упирается в то, что вы хотите дать поисковым роботам. был у меня опыт проектирования страницы для роботов - сделал точки входа - со статикой для роботов и АПИ для JS клиента=) а отлавл...
17 июля 2018 г. 9:43
Евгений Легоцкой

Django - Урок 035. Различные шаблоны для рендеринга разных типов контента в поисковой выдаче

Думаю, что это всё равно стоит оставить для индексирующих роботов поисковых систем, которые испоьлзуют простые GET запросы. Они же AJAX не используют. Так что полностью уйти от этого не получи...
Сейчас обсуждают на форуме
23 июля 2018 г. 11:24
Arrow

QComboBox делегат для QTableView

И можно еще один маленький вопрос: Как изменить значение в ячейке QTableView?
23 июля 2018 г. 8:56
Arrow

Получение прав пользователей на таблицу базы данных

Да, только самый основной прикол в том что для возможности редактирования таблицы пользователю одних прав на таблицу мало, нужны еще и на последовательность: GRANT USAGE O...
23 июля 2018 г. 8:52
Евгений Легоцкой

Перестал работать Qt Maintenance Tool

В настройках есть параметры прокси, возможно, через них сможете завести, через какой-нибудь прокси сервер. По поводу списка репозиториев. сам не в курсе. Спросил на официальном форум...
23 июля 2018 г. 7:59
Евгений Легоцкой

Qt Android

Так, по поводу ошибок, там в main.cpp ещё одна ошибка у вас Надо так написать QQmlApplicationEngine engine;engine.load(QUrl(QStringLiteral("qrc:/main.qml")));DBase myClas...
23 июля 2018 г. 6:44
Евгений Легоцкой

как проверить состояние у динамически созданного CheckBox в qml

Тогда можно расширить эту модель, наследоваться от неё. И добавить в качестве роли ещё и состояние чекбокса, для выбора. Также можно переопределить метод setData, чтобы можно было ус...

Рекомендуемые страницы