C++ (Qt)class ItemView : public QAbstractItemView // тут по идее нужен virtual{ Q_OBJECT public: ItemView(QWidget *parent) : QAbstractItemView(parent) { connect(this, SIGNAL(clicked(const QModelIndex &)), SIGNAL(currentItemChanged(const QModelIndex &))); } signals: void currentItemChanged(const QModelIndex &newIndex); protected:virtual void keyPressEvent(QKeyEvent *event){ QModelIndex oldIndex = currentIndex(); QAbstractItemView::keyPressEvent(event); // раньше, когда метод находился в классе-наследнике QListView, то вызывался просто для QListView int key = event->key(); if (key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Home || key == Qt::Key_End) if (oldIndex != currentIndex()) emit currentItemChanged(currentIndex());}};
C++ (Qt)class MyListView : public ItemView, public QListView{ Q_OBJECTpublic: explicit MyListView(QWidget *parent = 0) : ItemView(parent), QListView(parent) {}...};
C++ (Qt)ui.gearListView->installEventFilter(this);...bool ItemsViewerDialog::eventFilter(QObject *obj, QEvent *event){ if (event->type() == QEvent::KeyPress /*|| event->type() == QEvent::MouseButtonPress*/) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); QAbstractItemView *itemView = static_cast<QAbstractItemView *>(obj); QModelIndex oldIndex = itemView->currentIndex(); qApp->sendEvent(obj, event); // send keyPressEvent immediately int key = keyEvent->key(); if (key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Home || key == Qt::Key_End) if (oldIndex != itemView->currentIndex()) itemSelected(itemView->currentIndex()); return true; } return QDialog::eventFilter(obj, event);}
template <class T>class ItemView : public T{ Q_OBJECT public: ItemView(QWidget *parent) : T(parent) { connect(this, SIGNAL(clicked(const QModelIndex &)), SIGNAL(currentItemChanged(const QModelIndex &))); } signals: void currentItemChanged(const QModelIndex &newIndex); protected: virtual void keyPressEvent(QKeyEvent *event) { QModelIndex oldIndex = currentIndex(); T::keyPressEvent(event); int key = event->key(); if (key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Home || key == Qt::Key_End) if (oldIndex != currentIndex()) emit currentItemChanged(currentIndex()); }};
... ItemView<QListView> *view = new ItemView<QListView>(parentWidget); ItemView<QTableView> *table = new ItemView<QTableView>(parentWidget);
bool ItemsViewerDialog::eventFilter(QObject *obj, QEvent *event){ if (event->type() == QEvent::KeyPress /*|| event->type() == QEvent::MouseButtonPress*/) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); QAbstractItemView *itemView = static_cast<QAbstractItemView *>(obj); QModelIndex oldIndex = itemView->currentIndex(); QDialog::eventFilter(obj, event); int key = keyEvent->key(); if (key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Home || key == Qt::Key_End) if (oldIndex != itemView->currentIndex()) itemSelected(itemView->currentIndex()); return true; } return QDialog::eventFilter(obj, event);}
C++ (Qt)class ItemsViewerDialog : public QDialog{ Q_OBJECT ...protected: bool eventFilter(QObject *obj, QEvent *event); private slots: void itemSelected(const QModelIndex &index) { ... } void selectItem(); private: Ui::ItemsViewerWidget ui; QModelIndex _oldIndex; bool _wasAllowedKeyPressed; QAbstractItemView *_itemView;};
C++ (Qt)bool ItemsViewerDialog::eventFilter(QObject *obj, QEvent *event){ if (event->type() == QEvent::KeyPress || event->type() == QEvent::MouseButtonPress) { _itemView = static_cast<QAbstractItemView *>(obj); _oldIndex = _itemView->currentIndex(); if (event->type() == QEvent::KeyPress) { int key = static_cast<QKeyEvent *>(event)->key(); _wasAllowedKeyPressed = key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_PageUp || key == Qt::Key_PageDown || key == Qt::Key_Home || key == Qt::Key_End; } else _wasAllowedKeyPressed = true; QTimer::singleShot(0, this, SLOT(selectItem())); return false; } return QDialog::eventFilter(obj, event);} void ItemsViewerDialog::selectItem(){ if (_wasAllowedKeyPressed && _oldIndex != _itemView->currentIndex()) itemSelected(_itemView->currentIndex());}