Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ошибка в редакторе при работе в делегате, ошибка в редакторе при работе в делегате 
:(
    Опции темы
olegkuzn
Дата 16.11.2015, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



Здраствуйте знатоки Qt.

Помогите избавиться от ошибки.
При работе собственного редактора после вызова стандартного диалога открытия файла
необходимо записать значение полученное в в собственный виджет. Однако происходит аварийное
завершение программы. 

Выкладываю код. В комментариях постарался все подробно описать.

Код моего виджета
1. lineedit.h
Код

#ifndef LINEEDIT
#define LINEEDIT
#include <QLineEdit>
#include <QStyleOptionButton>

// создаем свой виджет "строка с кнопкой" на основе стандартного QLineEdit
// который будет использоваться как редактор в нашем делегате (class MyDelegate)
class LineEdit : public QLineEdit
{
    Q_OBJECT

public:
    LineEdit(QWidget* parent = 0);

private:
    int m_nRightMargin; // отступ от правого края для "кнопки"
    QStyleOptionButton m_optButton; // стиль кнопки

protected:
    // перегруженные ф-ции обработки событий
    virtual void paintEvent(QPaintEvent* event);
    virtual void mousePressEvent(QMouseEvent *);
    virtual void mouseReleaseEvent(QMouseEvent*);
};

#endif // LINEEDIT

2. lineedit.cpp
Код


#include "lineedit.h"
#include <QPainter>
#include <QApplication>
#include <QStyle>
#include <QMouseEvent>
#include <QFileDialog>

// конструктор
LineEdit::LineEdit(QWidget *parent)
        : QLineEdit(parent)
{
    m_nRightMargin = 20;
    setTextMargins(0,0,m_nRightMargin,0);
    setReadOnly(true);

    // определяем стиль и текст нашей "кнопки"
    m_optButton.text = "...";
    m_optButton.features = QStyleOptionButton::DefaultButton;
    m_optButton.state |= (QStyle::State_Raised | QStyle::State_Enabled );

}

void LineEdit::paintEvent(QPaintEvent *event)
{
    // отрабатываем стандарный paintEvent
    QLineEdit::paintEvent(event);

    QPainter painter(this);

    // определяем размеры "кнопки" на нашем виджете
    QRect rectBtn = event->rect();
    rectBtn.setLeft(rectBtn.width()-rectBtn.height());
    m_optButton.rect = rectBtn;

    // прорисовываем кнопку
    QApplication::style()->drawControl(QStyle::CE_PushButton,&m_optButton, &painter);
}

void LineEdit::mousePressEvent(QMouseEvent* event)
{
    // отрабатываем стандарный mousePressEvent
    QLineEdit::mousePressEvent(event);

    // если нажатие мыши произошло на месте кнопки нашего виджета
    if(m_optButton.rect.contains(event->pos()))
    {

        // изменяем состояние кнопки на нажатое и прорисовываем ее
        m_optButton.state |= QStyle::State_Sunken;
        update();

        // вызываем стандартный диалог открытия файла
        QString strFileName = QFileDialog::getOpenFileName( 0, QString("Журнал сканеров"), QDir::currentPath(),QString("любой файл, *.*"),0);

        // и если файл выбран то в св-во текст занести путь к файлу
        if(!strFileName.isEmpty())
            setText(strFileName);   // ВОТ ЗДЕСЬ И ПРОИСХОДИТ ОШИБКА
                                    // у меня создалось впечатление что при вызове
                                    // стандартного диалога редактор в делегате удаляется.
                                    // Подскажите как избежать такого поведения
    }
}

void LineEdit::mouseReleaseEvent(QMouseEvent *event)
{
    // отрабатываем стандарный mouseReleaseEvent
    QLineEdit::mouseReleaseEvent(event);

    // если отжатие мыши произошло на месте кнопки нашего виджета
    if(m_optButton.rect.contains(event->pos()))
    {
        // возвращаем "кнопку" в первоначальное состояние и прорисовываем виджет
        m_optButton.state &= !(QStyle::State_Sunken);
        m_optButton.state |= (QStyle::State_Raised | QStyle::State_Enabled );
        update();
    }
}



Заодно выкладываю реализацию своего делегата для класса QTableView
mydelegate.h
Код

#include "mydelegate.h"
#include <QPainter>
#include <QApplication>
#include <QPushButton>
#include <QFileDialog>
#include "lineedit.h"

QWidget* MyDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
   Q_UNUSED(option)
   Q_UNUSED(index )

   LineEdit* label = new LineEdit(parent);
   label->setText(index.data().toString());
   return label;
}

void MyDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
    LineEdit* lineEdit = (LineEdit*)editor;
    lineEdit->setText(index.data().toString());
}

void MyDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
    LineEdit* lineEdit = (LineEdit*)editor;
    QString str = lineEdit->text();
    model->setData(index, QVariant(str));
}


PM MAIL   Вверх
math64
Дата 16.11.2015, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



Я бы реализовал редактор так (у Вас редактор будет отображаться неправильно при длинном имени файла):
Код

class LineEdit : public QWidget
{
    Q_OBJECT

public:
    LineEdit(QWidget* parent = 0);
    ~LineEdit() { QDebug() << "~LineEdit"; } // Ловим момент когда редактор удаляется
    QLineEdit* editor() { return edit; }
private:
    QLineEdit* edit;
    QPushButton* button;
    QHBoxLayout* layout;

private slots:
    void onButtonClicked();
};

Если редактор действительно удаляется - будет вызван деструктор.
PM   Вверх
olegkuzn
Дата 16.11.2015, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



math64 Спасибо большое за предложенный вариант.
Я примерно так и реализовал редактор для делегата.
Все вроде бы работает.

Добавлено через 51 секунду
math64 Спасибо большое за предложенный вариант.
Я примерно так и реализовал редактор для делегата.
Все вроде бы работает.
PM MAIL   Вверх
olegkuzn
Дата 16.11.2015, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 84
Регистрация: 1.10.2007

Репутация: нет
Всего: нет



math64 Спасибо большое за предложенный вариант.
Я примерно так и реализовал редактор для делегата.
Все вроде бы работает.

Добавлено через 28 секунд
math64 Спасибо большое за предложенный вариант.
Я примерно так и реализовал редактор для делегата.
Все вроде бы работает.
PM MAIL   Вверх
math64
Дата 17.11.2015, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 23
Всего: 72



В Вашем первоначальном варианте, скорее всего, в mousePressEvent() нужно было бы установить флажок,
в mouseReleaseEvent() проверить этот флажок и emit'ить сигнал, а диалог вызывать в слоте.
Но я не уверен.
Кроме того, советую в делегате реализовать метод:
Код

class MyDelegate : public QStyledItemDelegate
{
    ...
    virtual QString displayText(const QVariant &value, const QLocale &locale) const;
    // или этот:
    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
};

и при длинном имени файла сокращать имена каталогов - по умолчанию будет обрезан конец строки.
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Кроссплатформенное программирование, QT/Gtk+/wxWidgets"
JackYF
Любитель
  • В заголовке темы в квадратных скобках обозначьте используемую вами библиотеку, например: [QT],[GTK],[wx].
  • Если вопрос актуален только для некоторой версии библиотеки, либо, если вы пользуетесь не самой последней версией, укажите это. Например: [QT4], [GTK2].
  • Все начинающие изучать Qt - не забудьте зайти сюда.
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • В вопросе укажите полную версию версию библиотеки, а также все дополнительные используемые программные пакеты.
  • Не забывайте пользоваться кнопкой "Код".
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к тематике этого раздела. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, Любитель.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets | Следующая тема »


 




[ Время генерации скрипта: 0.0439 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.