2016-01-13 2 views
1

Недавно я написал небольшое приложение с использованием Ruby и Qt. Это был мой первый нетривиальный проект с qtruby. Через некоторое время мне удалось перевести ссылки на C++ и учебные пособия в рабочий код Ruby, и он повесился.Ошибка приложения Qt/Ruby в Qt :: AbstractItemModel :: mimeData - Как найти и исправить причину?

Только при реализации моей собственной функции перетаскивания в QTreeView виджетах, я действительно застрял. Я мог бы изолировать проблему до метода Qt::AbstractItemModel::mimeData. После устранения некоторых других ошибок я получил следующий код, который каким-то образом вызвал ошибку crash, как только произошло действие перетаскивания.

class TreeModel < Qt::AbstractItemModel 
    def mimeData(indexlist) 
    encodedData = Qt::ByteArray.new("") 
    stream = Qt::DataStream.new(encodedData, Qt::IODevice::WriteOnly) 

    indexlist.each do |index| 
     if index.column == 0 
     if index.isValid 
      stream << index.item.mime_data.to_json 
     end 
     end 
    end 

    mimeData = Qt::MimeData.new 
    mimeData.setData("application/x-tegi.json", encodedData) 
    mimeData 
    end 
end 

Крушение оказалось недетерминированным, несколько раз только что сработавший код. Ошибка дампа и backtrace не дали мне подсказки, только, что авария произошла внутри QApplication::exec.

В чем проблема и как ее можно исправить?

ответ

1

Прототип C++ для mimeData является:

QMimeData * QAbstractItemModel::mimeData 
    (const QModelIndexList & indexes) const [virtual] 

Метод возвращает указатель на объект QMimeData. Моя реализация mimeData была , возвращая указатель на локальную переменную. Таким образом, детерминированные сбои.

Как только обнаружено, исправление проблемы было простым. Переменная экземпляра будет остаться в живых и держать свое значение до следующего вызова mimeData:

@mimeData = Qt::MimeData.new 
    @mimeData.setData("application/x-tegi.json", encodedData) 
    @mimeData 
end 

Другая возможность состоит в том, чтобы позвонить super и оставить строительство и деконструкции к суперкласса. Это также наследует данные мим по умолчанию («применение/х-qabstractitemmodeldatalist»):

mimeData = super 
    mimeData.setData("application/x-tegi.json", encodedData) 
    mimeData 
end 

Найдя вопрос, оказывается тривиальным мне. Тем не менее я хотел бы поделиться им, потому что я потратил слишком много времени на это. Документация qtruby предупреждает о аргументах указателя и упоминает некоторые неподдерживаемые функции, возвращающие указатели uchar, но ни слова о функциях, возвращающих указатели на объекты Qt. Будучи убаюканным qtruby, плавно обматывая типы данных туда и сюда, я так много раз смотрел на эту маленькую звездочку, не заметив ее.

Смежные вопросы