gpt4 book ai didi

c++ - Qt::Popup 破坏 QScroller 动态滚动?

转载 作者:太空狗 更新时间:2023-10-29 22:55:45 31 4
gpt4 key购买 nike

首先,我的问题只能在带触摸屏的设备上重现,使用 PC/鼠标一切正常。

问题是,如果我使用 QTableView + QScroller 作为独立窗口一切正常 - 我将手指从底部移动到顶部内容向下滚动,从上到下滚动向上.

但是,如果我将 QTableView 放在 QWidget 中并带有 Qt::Popup 属性,则滚动会改变方向!我从下往上移动手指,它向上滚动,从上到下向下滚动。

这是我的代码:

#include <QAbstractTableModel>
#include <QScroller>
#include <QTouchDevice>
#include <QVBoxLayout>
#include <QtDebug>
#include <QtWidgets/QApplication>
#include <QtWidgets/QTableView>

class MyModel : public QAbstractTableModel {
public:
MyModel(QObject *parent) : QAbstractTableModel(parent) {}

int rowCount(const QModelIndex &parent = QModelIndex()) const override {
return 100;
}
int columnCount(const QModelIndex &parent = QModelIndex()) const override {
return 3;
}
QVariant data(const QModelIndex &index,
int role = Qt::DisplayRole) const override {
if (role == Qt::DisplayRole) {
return QString("Row%1, Column%2")
.arg(index.row() + 1)
.arg(index.column() + 1);
}
return QVariant();
}
QVariant headerData(int section, Qt::Orientation orientation,
int role) const override {
if (role == Qt::DisplayRole) {
if (orientation == Qt::Horizontal) {
switch (section) {
case 0:
return QString("first");
case 1:
return QString("second");
case 2:
return QString("third");
}
}
}
return QVariant();
}
};

bool is_touch_screen_avaible() {
const auto devs = QTouchDevice::devices();
for (const auto &dev : devs) {
if (dev->type() == QTouchDevice::TouchScreen) {
return true;
}
}
return false;
}

void configure_scoller_for_item_view(QAbstractItemView *view) {
QScroller *scroller = QScroller::scroller(view);
view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
QScrollerProperties properties =
QScroller::scroller(scroller)->scrollerProperties();
QVariant overshootPolicy =
QVariant::fromValue<QScrollerProperties::OvershootPolicy>(
QScrollerProperties::OvershootAlwaysOff);
properties.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy,
overshootPolicy);
scroller->setScrollerProperties(properties);
properties.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy,
overshootPolicy);
scroller->setScrollerProperties(properties);
if (is_touch_screen_avaible())
scroller->grabGesture(view, QScroller::TouchGesture);
else
scroller->grabGesture(view, QScroller::LeftMouseButtonGesture);
}

#define POPUP

int main(int argc, char *argv[]) {
QApplication a(argc, argv);
#ifdef POPUP
QWidget *mainWin = new QWidget;
mainWin->setWindowFlags(Qt::Popup);
auto lay = new QVBoxLayout(mainWin);
mainWin->setLayout(lay);
auto tableView = new QTableView(mainWin);
lay->addWidget(tableView);
#else
auto tableView = new QTableView;
#endif
MyModel myModel(nullptr);
tableView->setModel(&myModel);
tableView->setSelectionMode(QAbstractItemView::NoSelection);
tableView->setFocusPolicy(Qt::NoFocus);
configure_scoller_for_item_view(tableView);

#ifdef POPUP
mainWin->resize(500, 500);
mainWin->show();
#else
tableView->resize(500, 500);
tableView->show();
#endif

return a.exec();
}

最佳答案

Qt 没有在可滚动区域中完全实现手势 explained in their own documentation :

Qt does not really reflect the system behavior wrt gestures on scrollable views (widget classes inheriting QAbstractItemView, QML classes) well.

[...]

In widgets, the pan recognizer is currently hard-coded to use 2 touch points. For touchscreens, it should be changed to one. But that can't be done as long as single-finger-panning is reserved for selecting text.

When using a touch screen, the selection in widgets is driven by mouse events synthesized from touch by the system (Windows) or Qt itself (other platforms). The same touch events drive QGestureManager.

另一方面,有一个known (和 old )QTouchEvents 和弹出窗口部件的未定义行为:

The behavior of QTouchEvents is undefined when opening a pop-up or grabbing the mouse while there are more than one active touch points.

可能这两个问题的结合是您问题的根源。

作为一种可能的解决方法(虽然不完全是您想要的),您可以使用 QWidget::grabGesture(Qt::PanGesture) 启用双指滚 Action 为替代方案。另外,正如@mohammad-kanan 在评论中提到的,您可以尝试使用 Qt::FramelessWindowHint | Qt::Tool 而不是 Qt::Popup

关于c++ - Qt::Popup 破坏 QScroller 动态滚动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50491050/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com