1

最近、Ruby と Qt を使用して小さなアプリケーションを作成しました。これは、qtruby を使用した最初の重要なプロジェクトでした。しばらくして、C++ のリファレンスとチュートリアルを実用的な Ruby コードに変換し、コツをつかみました。

ウィジェットに独自のドラッグ アンド ドロップ機能を実装するときだけ、 QTreeView本当に行き詰まりました。Qt::AbstractItemModel::mimeData問題をメソッドに切り分けることができました。他のいくつかの間違いを取り除いた後、ドラッグ操作が発生するとすぐにアプリケーションがクラッシュする原因となった次のコードになりました。

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

クラッシュは非決定論的で、数回コードが機能しているように見えました。エラー ダンプとバックトレースからヒントは得られませんでしたが、内部でクラッシュが発生したことだけがわかりましたQApplication::exec

何が問題で、どのように修正できますか?

4

1 に答える 1

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

もう 1 つの可能性はsuper、スーパークラスに構築と分解を呼び出して任せることです。これは、デフォルトの MIME データ ("application/x-qabstractitemmodeldatalist") も継承します。

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

問題を見つけた後、それは私には些細なことのように見えます。それでも時間を無駄にしたのでシェアしたいと思います。qtruby のドキュメントでは、ポインター引数について警告し、ポインターを返すサポートされていない関数について言及していますucharが、Qt オブジェクトへのポインターを返す関数については言及していません。データ型を前後にシームレスにラップする qtruby に心を奪われて、私はその小さなアスタリスクを何度も見ましたが、それを見つけることができませんでした。

于 2016-01-13T16:19:57.173 に答える