Qt中QTableWidget的鼠标跟踪问题

3

我希望使用Qt4.7在QTableWidget中启用鼠标跟踪(mouseTracking)。通常可以通过设置setMouseTracking(true)来实现。但是在QTableWidget上却不起作用。是否有什么特殊处理方式才能激活鼠标跟踪功能?

尽管我正在进行更复杂的操作,但通过在mouseMoveEvent中打印出QMouseEvent.x(),我可以获得信心,证明这一功能未被启用。感谢您到目前为止所做的工作 :)

以下是我尝试过的:

    QGridLayout * layout = new QGridLayout(this);
    SCTableWidget * aTable = new SCTableWidget(tableRows, tableCols, this);

    QTableWidgetItem * newItem;
    for(int i = 0; i<(3); i++) {
        for(int j = 0; j<(17); j++) {
            newItem = new QTableWidgetItem(QString::number(tableData[i][j]));
            aTable->setItem(i,j, newItem);
        }
    }

// First try
    aTable->setMouseTracking(true);

//Second try. Main Window further down.
    MainWindow::instance->enableMouseTracking(aTable->children());
    MainWindow::instance->enableMouseTracking(aTable->viewport()->children());


// Third try
    aTable->viewport()->setMouseTracking(true);

    layout->addWidget(aTable, 0, 0, 1, 2);

第二次尝试包含了一种在MainWindow中实现的方法,它看起来像这样:

void
MainWindow::enableMouseTracking(const QObjectList & pChildren)
{
  foreach(QObject * obj, pChildren)
  {
    QWidget * w = qobject_cast<QWidget *>(obj);

    if(w)
    {
      w->setMouseTracking(true);
      enableMouseTracking(w->children());
    }
  }
}

对于良好记录努力解决问题的人,加1。 - Jichao
3个回答

3

开启QTableWidget->viewport()的鼠标跟踪通常是有效的。你是否也在捕获QTableWidget->viewport()小部件的鼠标事件?请检查下面的示例是否适合您:

test.h:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

    bool eventFilter(QObject *obj, QEvent *event);

private:
    Ui::MainWindow *ui;
    QTableWidget *table;
};

test.cpp:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    table = new QTableWidget(5, 10, this);
    table->setGeometry(10, 20, 300, 200);

    for (int row=0; row<5; ++row)
        for (int column=0; column<10; ++column)
            table->setItem(row, column, new QTableWidgetItem(tr("%1").arg((row+1)*(column+1))));

    table->setMouseTracking(true);
    table->viewport()->setMouseTracking(true);
    table->installEventFilter(this);
    table->viewport()->installEventFilter(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
    if (obj == table)
    {
        if (event->type() == QEvent::MouseButtonPress)
            qDebug() << "table mouse press event";
        else if (event->type() == QEvent::MouseMove)
            qDebug() << "table mouse moveevent";
    }
    else if (obj == table->viewport())
    {
        if (event->type() == QEvent::MouseButtonPress)
            qDebug() << "table->viewport mouse press event";
        else if (event->type() == QEvent::MouseMove)
            qDebug() << "table->viewport mouse moveevent";
    }
    return QMainWindow::eventFilter(obj, event);
}

希望这能帮到你,问候。

谢谢!我没有想到可以把事件过滤器连接到视口上。现在我正在事件过滤器中处理一些事件。这样做是否好的风格呢? - Patrick R.
根据我的理解,事件过滤器是完全可以的:http://doc.qt.nokia.com/latest/eventsandfilters.html - serge_gubenko

2

默认情况下,鼠标事件被禁用,因为QAbstractItemView实现了mousePressEventmouseReleaseEvent等函数,而QTableWidget根本不实现它们,这意味着鼠标消息被QAbstractItemView中的函数阻止。

因此,解决此问题的一种非常简单的方法是子类化QTableWidget类,并自己提供鼠标信号,这应该非常容易,只需尝试即可!


0
这对我有用:
    aTable->setMouseTracking(true);
    aTable->viewport()->setMouseTracking(true);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接