11 апреля 2019 г. 10:01

Qt

Delegate, qcheckbox, qcheckbox center, QTableView

Доброго времени суток.
Возникла необходимость использовать делегат для отображения QCheckBox в таблице (выбирать объекты из списка для последующей работы с ними).
Для того чтобы разобратся с делегатами создал небольшой проект.
На выходе получаем следующее:

22 января 2019 г. 13:45
IscanderChe

Всем добрый день.

Суть задачи: надо, чтобы в одной из колонок QTableView вместо хранимого в QSqlTableModel значения выводился чекбокс и при смене состояния чекбокса значения в базе тоже менялось. С помощью ItemIsUserCheckable проблему удалось решить.

Есть ли вариант решения с помощью кастомного делегата? У меня получается только частично: чекбокс виден только при щелчке на ячейку, данные исправно меняет, но при переходе к другой ячейке чекбокс заменяется данными.

class CheckBoxDelegate : public QStyledItemDelegate
{
    Q_OBJECT

public:
    CheckBoxDelegate(QObject* parent = 0);

    QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
                          const QModelIndex& index) const override;

    void setEditorData(QWidget* editor, const QModelIndex& index) const override;
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override;

    void updateEditorGeometry(QWidget *editor,
            const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
QWidget* CheckBoxDelegate::createEditor(QWidget* parent,
    const QStyleOptionViewItem& option,
    const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        QCheckBox* editor = new QCheckBox(parent);
        return editor;
    }

    return QStyledItemDelegate::createEditor(parent, option, index);
}

void CheckBoxDelegate::setEditorData(QWidget* editor,
    const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        int value = index.model()->data(index, Qt::EditRole).toBool();
        QCheckBox* checkBox = static_cast<QCheckBox*>(editor);
        checkBox->setChecked(value != 0);
    }
}

void CheckBoxDelegate::setModelData(QWidget* editor,
    QAbstractItemModel* model, const QModelIndex& index) const
{
    if(index.column() == 1)
    {
        QCheckBox* checkBox = static_cast<QCheckBox*>(editor);
        bool value = checkBox->isChecked();
        model->setData(index, value, Qt::EditRole);
    }
}

void CheckBoxDelegate::updateEditorGeometry(QWidget* editor,
    const QStyleOptionViewItem& option, const QModelIndex& index) const
{
    editor->setGeometry(option.rect);
}
28 декабря 2018 г. 8:20
Михаиллл

Здравствуйте. В QDialog создал TableView и пытаюсь опрределить его индекс. Дебаг возвращает:setGeometry: Unable to set geometry 116x30+2100+419 on QWidgetWindow/'QDialogClassWindow'. Resulting geometry: 178x122+2100+419 (frame: 8, 30, 8, 8, custom margin: 0, 0, 0, 0, minimum size: 178x122, maximum size: 16777215x16777215). Скажите пожалуйста, как узнать индекс?

QDialog dlg(this);
        dlg.setWindowTitle(tr("Выберите активную вакансию"));

        QSqlTableModel *SearchTableModel = new QSqlTableModel(this);
        SearchTableModel ->setTable(NameTableVacancy);
        SearchTableModel->select(); 

        QTableView *ActiveVacancy = new QTableView(&dlg);
        //отображение бд
        ActiveVacancy->setModel(SearchTableModel);
        ActiveVacancy->setSelectionBehavior(QAbstractItemView::SelectRows);  //Разрешаем выделение строк
        ActiveVacancy->setSelectionMode(QAbstractItemView::SingleSelection); //Устанавливаем режим выделения лишь одно строки в таблице

        QDialogButtonBox *btn_box = new QDialogButtonBox(&dlg);
        btn_box->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);

        connect(btn_box, &QDialogButtonBox::accepted, &dlg, &QDialog::accept);
        connect(btn_box, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);

        QFormLayout *layout = new QFormLayout();
        layout->addRow(ActiveVacancy);
        layout->addWidget(btn_box);

        dlg.setLayout(layout);

        // В случае, если пользователь нажал "Ok".
        if(dlg.exec() == QDialog::Accepted)
        {
            qDebug()<<ActiveVacancy->currentIndex();

        }
26 декабря 2018 г. 16:38
Михаиллл

Здравствуйте. Как узнать что QTableView пуст? Тут пока работает

    QModelIndex IndexForTableView = ui->AllVacancyCompanyTableView->currentIndex();
    qDebug()<<IndexForTableView;

Выдает: QModelIndex(-1,-1,0x0,QObject(0x0)) Дальше пишу:

qDebug()<< ui->AllVacancyCompanyTableView->model()->data(ui->AllVacancyCompanyTableView->model()->index(IndexForTableView.row(),0),0);

и на этом моменте вылетает, хотя по логике должно выдавать "-1"

i
24 августа 2017 г. 21:05
ironexmaiden

Hello guys I have a problem using table view. I have a tableview connected with a QSqlTableModel. On its 2nd column I want to have check state to control the row's Status (active/inactive) but when I try to push the check box QTableView scrolls to the bottom and returns to it's previous position. Is there any solution?

    bool ProjectsModel::setData(const QModelIndex &index, const QVariant &value, int role)
    {
        if(index.column() == STATUS_INDEX) {
            QSqlRecord rec = this->record(index.row());
            QString qrstr;
     
            qrstr = (rec.field(index.column()).value().toInt() == 1) ? "update " + tableName() + " set Status=0 where BRACE_ID=" : "update " + tableName() + " set Status=1 where BRACE_ID=";
            qrstr += QString().setNum(index.row()+1);
     
            braceDatabase->exec(qrstr.toUtf8().constData());
            return true;
        }
     
        return false;
    }
     
    void DataBase::updateTablesSlot()
    {
        if(projectsModel)
            projectsModel->select();
        if(attributesModel)
            attributesModel->select();
        if(targetsModel)
            targetsModel->select();
    }
     
    void DataBase::exec(const std::string &querystr)
    {
    		QSqlQuery qr(db);
            qr.exec(querystr.c_str());
            //qDebug() <<"Command :" << querystr.c_str() << "-> "<< query->lastError().text();
            updateTables(); 
    }
15 июня 2017 г. 6:58

Qt

Qt, QStandardItemModel, QMultiMap, QTableView

QMultiMap является классом, наследованным от QMap, который позволяет хранить несколько значений для одного ключа. То есть ключ может повторяться. Этот класс может быть использован, например, для представления словаря синонимов.

Напишем небольшую программу, которая будет содержать две таблицы:

  1. Таблицу с ключами
  2. Таблицу со значениями, которые будут являться синонимами слов в первой таблице.

Изначально таблица с ключами будет заполнена, тогда как таблица со значениями будет пустой. При клике по строке в таблице ключей, таблица значений будет заполняться синонимами того слова, по строке которого был произведён клик.

Внешний вид приложения:

KL
29 января 2017 г. 20:26
Konstantin Lazarev

Подскажите пожалуйста как применит css к ячейкам таблицы? Как установить фиксированные размеры ячеек таблицы?

12 января 2017 г. 18:53
Arrow

Подскажите как можно в QTableView реализовать отслеживание нажатия клавиш.

Версия Qt 5.7.

Для решения задачи решил наследоваться от QTableView и переопределить метод keyPressEvent. ниже привожу свой код и подробное описание, что делал.

Файл mtableview.h:

#ifndef MTABLEVIEW_H
#define MTABLEVIEW_H

#include <QObject>
#include <QTableView>
#include <QKeyEvent>

class QTableViewPrivate;

class MTableView : public QTableView
{
public:
    MTableView(QWidget *parent = 0);
    MTableView(QTableViewPrivate &d, QWidget *parent);
signals:
    void keyPressEvent(QKeyEvent *event);
};

#endif // MTABLEVIEW_H

Файл mtableview.cpp:

#include "mtableview.h"

MTableView::MTableView(QWidget *parent):
    QTableView(parent)
{ }

MTableView::MTableView(QTableViewPrivate &d, QWidget *parent)
    : QTableView(d, parent)
{ }

void MTableView::keyPressEvent(QKeyEvent *event)
{
    QTableView::keyPressEvent(event);
}

После чего в дизайнере для элемента QTableView на форме указал "Преобразовать в" и указал свой класс MTableView (все работает)

Ошибки начались при реализации метода keyPressEvent в программе:

connect(ui->lView, &MTableView::keyPressEvent, this, &Wnd::keyPressEvent);
void Wnd::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return)
    {
        on_lView_doubleClicked(ui->lView->currentIndex());
    }
}

Выдает ошибки:

/gcc_64/include/QtCore/qobject.h:-1: In instantiation of 'static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) [with Func1 = void (MTableView::*)(QKeyEvent*); Func2 = void (FManagerWnd::*)(QKeyEvent*); typename QtPrivate::FunctionPointer<Func>::Object = MTableView; typename QtPrivate::FunctionPointer<Func2>::Object = FManagerWnd]':

/gcc_64/include/QtCore/qglobal.h:746: ошибка: static assertion failed: No Q_OBJECT in the class with the signal
 #define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)
                                               ^

/gcc_64/include/QtCore/qobject.h:226: in expansion of macro 'Q_STATIC_ASSERT_X'
         Q_STATIC_ASSERT_X(QtPrivate::HasQ_OBJECT_Macro<typename SignalType::Object>::Value,
         ^

Не могу разобраться, что не так.

P.S. Извините за столько текста :)

9 января 2017 г. 15:42
Arrow

Для работы с QFileSystemModel использую QTableView. В нем отображаются заголовки колонок: name, size и т.д.

Как можно изменить отображаемые имена заголовков?

И второй вопрос как установить растягивание одной из колонок, чтобы она занимала все сободное пространство?

Для работы с шириной колонок нашел только метод

setColumnWidth()
KL
6 января 2017 г. 19:40
Konstantin Lazarev

Подскажите пожалуйста, как работать с таблицами. Как сделать заполнение ячеек текстом.

s
26 мая 2019 г. 14:33
simpleunderground

Qt - Тест 001. Сигналы и слоты

  • Результат:31баллов,
  • Очки рейтинга-10
НД
25 мая 2019 г. 23:25
Николай Демиденко

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

  • Результат:64баллов,
  • Очки рейтинга-1
НД
25 мая 2019 г. 23:19
Николай Демиденко

C++ - Тест 002. Константы

  • Результат:50баллов,
  • Очки рейтинга-4
Последние комментарии
21 мая 2019 г. 20:10
Дмитрий

Приветствую! Я думаю дойдёт и до этого, но пока изучать его у меня нет желания.
20 мая 2019 г. 19:20
Евгений Легоцкой

Добрый день! Вы не думали разместить репозиторий проекта на GitHub?
P.
18 мая 2019 г. 14:03
PELMYACH .

Спасибо большое! Вскоре буду разбираться!
18 мая 2019 г. 9:13
Евгений Легоцкой

Добрый день! Отнимать значение общего счётчика можно в деструкторе класса кнопки QDynamicButton::~QDynamicButton(){ ResID--;} При этом я бы ещё переустанавливал значения вс...
P.
14 мая 2019 г. 22:33
PELMYACH .

Здравствуйте!А не подскажите, как можно при удалении какой либо кнопки, у щётчика отнять значение?Дабы например четвёртой кнопке соответствовал ID 4, а не 5 скажем
Сейчас обсуждают на форуме
26 мая 2019 г. 6:49
Михаиллл

Скачал dll от сюда и заработало
24 мая 2019 г. 6:48
Евгений Легоцкой

Если там будут только перечисления внутри namespace, то жа, достаточно будет заголовочного файла
24 мая 2019 г. 6:28
Андрей Янкович

работает любой http сервер, и можно использовать обсалютно любой портпример <RemoteRepositories> <Repository> <Url>http://178.124.160.6:3030/A/B&l...;
23 мая 2019 г. 10:42
Михаиллл

Спасибо, помогло.
23 мая 2019 г. 6:31
Евгений Легоцкой

Для задач и граф-то не нужен. Достаточно будет таблицы в локальной базе данных SQLite, в которой указывается задача, время и т.д. В этом разделе есть примеры по работа с базой д...
25,000.00 руб. - 30,000.00 руб.
Разработчик Qt/C++
Barnaul, Altai Krai, Russia

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы

EVILEG
О нас
Услуги
Присоединяйтесь к нам
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB