1

スプリッターベースのビューを備えた Qt アプリケーションがあります。左側には、選択可能なファイルを含む QListWidget があります。選択したファイルの内容は、スプリッターの右側に適切な形式で表示されます。この部分は正常に動作します。

ここで、比較機能を追加する必要があります。QListWidget で 1 つの項目が選択されている場合、その内容が右側に表示されます。別のアイテムが選択されている場合は、代わりに差分結果を表示したいと思います。(すべての項目を比較できるわけではないため、これよりも少し複雑です。)

私がやりたいのは、単一の選択機能をそのままにして、2番目の選択でCTRL +マウスクリックのみを有効にすることです。QAbstractItemView::ExtendedSelection を使用してから、Shift とマウスのドラッグを除外しようとしましたが、そのアプローチではうまくいきませんでした: keyPressEvent() で Shift キーをキャプチャできましたが、選択を防ぐことはできませんでした (イベントをドロップするだけで十分だと思っていました)。ドラッグに関しては、状態が DragSelectingState に変化したときにイベントをドロップすることを期待して mouseMoveEvent() を使用しましたが、それも機能しませんでした。

次に、単一選択に固執することを検討しましたが、2番目のアイテムを右クリックしてコンテキストメニューを開くことを検討しました-右クリックはitemSelectionChanged()シグナルを発しますが、どのアイテムがわからないため、これをどうするかまだわかりません右クリックされました。

追加の UI 要素を追加することを含まない他のクリエイティブな提案を受け入れます。追加のボタンやコンボ ボックスなどは使用できません。

4

1 に答える 1

0

QListWidget での選択を 1 つまたは 2 つに制限する方法はまだわかりませんが、2 番目の項目を右クリックするとコンテキスト メニューが機能します。

選択モードを QAbstractItemView::SingleSelection に設定してから、mousePressEvent() と contextMenuEvent() を再実装するだけです。

class MyListView : public QListWidget
{
  Q_OBJECT

  public:
    ListView();
    virtual ~ListView() {}

    /** Add item to the list. 
        @param itemName Item's display name.
        @param itemHandle Value to return if item selected.
    */
    void AddItem(const QString itemName, const quint32 itemHandle);

  private slots:
    void slot_ItemSelectionChanged(void);
    void slot_Option1(void);
    void slot_Option1(void);

  signals:
    void signal_ItemSelectionChanged(const qint32 itemHandle);

  private:
    void mousePressEvent(QMouseEvent* mousePressEvent);
    void contextMenuEvent(QContextMenuEvent* menuEvent);

    QListWidgetItem *m_selectedItem;        ///< Pointer to the currently selected item.
    QListWidgetItem *m_rightClickedItem;    ///< Pointer to right-clicked item in the list.
    QAction* m_menuOption1;                 ///< Menu option 1.
    QAction* m_menuOption2;                 ///< Menu option 2.
    QMenu* m_myListContextMenu;             ///< Menu with all List View menu actions.
};

MyListView::MyListView()
{
  setSelectionMode(QAbstractItemView::SingleSelection);

  // create my context menu with 2 options
  m_menuOption1 = new QAction(tr("option 1"), this);
  m_menuOption1 ->setEnabled(true);

  m_menuOption2 = new QAction(tr("option 2"), this);
  m_menuOption2 ->setEnabled(true);

  m_myListContextMenu = new QMenu(this);
  m_myListContextMenu ->addAction(m_menuOption1);
  m_myListContextMenu ->addAction(m_menuOption2);

  bool allConnected = true;
  // process primary selection
  allConnected &= connect(this, SIGNAL(itemSelectionChanged(void)), this, SLOT(slot_ItemSelectionChanged(void)));
  // process menu option 1
  allConnected &= connect(m_menuOption1, SIGNAL(triggered()), this, SLOT(slot_Option1()));
  // process menu option 2
  allConnected &= connect(m_menuOption2, SIGNAL(triggered()), this, SLOT(slot_Option2()));

  if (!allConnected )
  {
    assert(0);
  }
}

void ListView::slot_ItemSelectionChanged(void)
{
  if (currentItem() != m_selectedItem)
  {
    m_selectedItem = currentItem();
    emit signal_ItemSelectionChanged(m_selectedItem->type());
  }
} // end of method slot_ItemSelectionChanged()

void MyListView::contextMenuEvent(QContextMenuEvent* menuEvent)
{
  m_rightClickedItem = itemAt(menuEvent->pos());

  // do my prep stuff here specific to right-clicked item 
  // in case one of menu options gets selected

  m_listMenu->exec(menuEvent->globalPos());
} // end of method contextMenuEvent()

void MyListView::mousePressEvent(QMouseEvent* mousePressEvent)
{
  // drop right mouse button event as it would otherwise cause a change of selection
  if (!(mousePressEvent->buttons() & Qt::RightButton))
  {
    QListWidget::mousePressEvent(mousePressEvent);
  }
} // end of method mousePressEvent()
于 2012-06-07T22:12:45.070 に答える