Kohshi's Blog
2013/12/27
QTableViewでTable内のRowをDrag&DropでMoveだけさせる
年明けにやるんだけど忘れないようにメモ。 Qtで表とかSpreadsheetを追加したい場合はQTableViewというのを使うのが便利なんだけど、 Drag&DropでRowの位置を変更したいという場合結構ありそうな気がするんだけどもわりとやり方がめんどくさい。 以下のサイトでも質問されているけど自分がやりたい方法で実現してない * [QTableView drag move rows](http://stackoverflow.com/questions/12168610/qtableview-drag-move-rows) * [QTableView reorder rows in table](http://www.linkedin.com/groups/QTableView-reorder-rows-in-table-1531497.S.218641029) 2番めの投稿にもある通り、QTableView::verticalHeader()->setMovable(true)(setSelectionMovableは古い)すれば、 表のセルでなくてHeaderをDrag&DropすることでMoveできる。 これでもいいんだけど、やっぱりセル自体をDrag&Dropできたほうが直感的。という事で追加で調べてみた。 使うのはQTableViewとQStandardItemModelとQStandardItemというQTableViewを使う場合には もっともポピュラーだと思われる方法。 QTableViewの配置はQt Designerで↓のように配置して
QTableViewの設定から以下の項目をセット | key | value | | ---- | ---- | | QWidget::acceptDrops| true | | QAbstractItemView::dragEnabled| true | | QAbstractItemView::dragDropOverwriteMode| false | | QAbstractItemView::dragDropMode| InternalMove | | QAbstractItemView::defaultDropAction| MoveAction | | QAbstractItemView::selectionBehavior| SelectRows | 一つ一つON/OFFしてないので不要なものも入ってるかも。 一見上記の設定だけでもMoveだけを許可してdragDropOverwriteModeをfalseにしてるのでうまくいきそうな感じがするんだが、 このままQStandardItemをセットするとDrag&Dropでセルとセルの間を選ぶとMoveされるんだけど、 セル自体を選ぶと上書きされてしまう。これを防ぐ方法がわからなくて困った。 ヒントになったのは以下 * [QAbstractItemView Class Reference dragDropOverwriteMode](http://qt-project.org/doc/qt-4.8/qabstractitemview.html#dragDropOverwriteMode-prop) `Note: This is not intended to prevent overwriting of items. The model's implementation of flags() should do that by not returning Qt::ItemIsDropEnabled.` ”これ(=dragDropOverwriteMode)はitemを上書きするのを防がない。flags()の実装でQt::ItemIsDropEnabledを返さない事で上書きを防げる。” ということはQStandardItemModelを継承してflags()をreimplementしてQt::ItemIsDropEnabledのFlagを下ろせばいいのかとおもったんだが・・ 以下のようにMyItemModelを作ってQStandardItemModelの代わりにnewしてQTableView::setModel()しても現象は変わらない・・。 ```cpp class MyItemModel : public QStandardItemModel { public: MyItemModel(QObject * parent = 0) : QStandardItemModel(parent){} MyItemModel(int rows, int columns, QObject * parent = 0) : QStandardItemModel(rows, columns, parent) {} virtual Qt::ItemFlags flags()const{ return (QStandardItemModel::flags() & ~Qt::ItemIsDropEnabled); } }; ``` うーん。 じゃあModelをQStandardItemModelに戻して今度は以下のように各QStandardItem::setFlagでQt::ItemIsDropEnabledをOFFしてみたら Item同士の上書きがなくなった! ```cpp QStandardItem *item = new QStandardItem(QString("item00")); item->setFlags(item->flags() & ~Qt::ItemIsDropEnabled); mpModel->setItem(0, 0, item); ``` こんな感じ。
なんかMoveした瞬間に一瞬一列増えて消えてをしてるような気もするが・・。
ツイート
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿