PDA

View Full Version : QTabWidget / mouseMoveEvent



migel
7th October 2011, 13:26
Its me again

Problem with moiseMoveEvent on the Tab widgets. It does not work on mac.

When I add two tab widgets and on default switch to second one programatically


tabWidget()->setCurrentWidget(secondpage);

switching back two first one using GUI mouseMoveEvent does not work.

When I add two tabs without switching "setCurrentWidget(secondpage)" , then clicking on GUI tabs back and forward mouse event always work.

The below is what I do. I have setMoveMouse set everywhere.


void MainWindow::currentTabChanged(int index)
{

QWidget *widget = _tabWidget->widget(index);

if (widget) {
_tabWidget->setCurrentWidget(widget);
widget->setFocus(Qt::ActiveWindowFocusReason);
widget->activateWindow();
widget->raise();
widget->setVisible(true);
Application::setActiveWindow(widget);
}
}

What I am missing here ?

Thanks for help

wysota
7th October 2011, 21:06
What is "setMoveMouse"?

migel
8th October 2011, 20:29
I meant


setMouseTracking(bool)

wysota
9th October 2011, 09:36
Why did you enable mouse tracking?

migel
9th October 2011, 17:45
to track the mouse event ?

wysota
9th October 2011, 18:00
Did you read the docs for this method? I really doubt you want to use it.

migel
9th October 2011, 18:31
"If mouse tracking is disabled (the default), the widget only receives mouse move events when at least one mouse button is pressed while the mouse is being moved.
If mouse tracking is enabled, the widget receives mouse move events even if no buttons are pressed."

I don't want to track the mouse when a button is pressed. I want track it when ever I mouse over on ? So I guess I need it enabled. No ?

Explain if no please ?

wysota
10th October 2011, 07:42
I don't want to track the mouse when a button is pressed. I want track it when ever I mouse over on ? So I guess I need it enabled. No ?

Have you considered the fact that QTabWidget already handles mouse events and expects to receive mouse move events only when mouse button is pressed and that you are breaking this functionality with mouse tracking? Also, do your mouse event handlers reimplementations assure that the original functionality is retained? And do you really think I asked why did you enable mouse tracking to hear "because I want to track the mouse"?

migel
10th October 2011, 09:53
I am apologize for "because I want to track the mouse" if that hurt you feelings. But if QTabWidget handles mouse events and expects to receive mouse move only when mouse button is pressed so how to fix that if not putting mouse tracking ? I don't want to press the button.

Also that what I know of any QWidget defaults to receive mouse move event when button is pressed, and doc says that to enable it you gotta enable mouse move tracking.

So if you saying it actually breaking it so I am very confused. Any way removing it does not fix it. Still need to press the btn to receive the mouse event.

Any way did not put it into QtabWidget only for a widget added to the TAB and to mainwindow. Adding it to QTabWidget does not help as well.

Thanks for help

wysota
10th October 2011, 09:58
I am apologize for "because I want to track the mouse" if that hurt you feelings.
Don't worry about my feelings. You are just wasting your time giving such answers. And risk me losing my patience and stopping trying to help you.


But if QTabWidget handles mouse events and expects to receive mouse move only when mouse button is pressed so how to fix that if not putting mouse tracking ? I don't want to press the button.
What do you want? Or let me make myself more explicit... what is the ultimate goal you are trying to obtain by handling mouse events in this particular situation?

migel
10th October 2011, 10:25
Each QTabWidget TAB is different. One of the tab is actually a QTableView. In this QTableView I have built a delegate for rows to display text as a hyper links which totally does not work for on mac . Below code works for linux and win, so text is underlined on mouse over a row on a text. I need to put the cursor: pointer as well to really look like a hyperlinks.
This does not work even for linux and win.


if (optionV4.state & QStyle::State_MouseOver) {
doc.setDefaultStyleSheet("a:hover {text-decoration: underline; cursor:pointer;}");
} else {
doc.setDefaultStyleSheet("a {text-decoration: none;cursor:pointer;}");
}

So instead thought I will get at least working changing cursor by using mouseMoveEvent for all platforms


void Table::mouseMoveEvent(QMouseEvent *event)
{

this->setCursor( QCursor( Qt::ArrowCursor ));

QModelIndex index = indexAt( event->pos());
QStandardItem *item = model()->itemFromIndex(_proxyModel->mapToSource(index));
if (item)
{
if (item->column() == 4 || item->column() == 3 || item->column() == 1 )
{
this->setCursor( QCursor( Qt::PointingHandCursor ));
}

}
}


But a code above works just for a linux and win. No MAC.

For mac behave is different. When I mouseOver on row nothing happening. But when I press and don't let the mouse button, moving around rows it's doing the job, cursor is changing just fine. But I don't really want to keep the button. It must behave like hyperlinks so thought setMouseTracking will fix it.

Was wrong it must be something else.


The real code of QTabWidget for my table keeps the QWidget with controls and table

so



QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(controls);
layout->addWidget(MyTable()); <- here is my QTableView

QWidget *activitiesPage = new QWidget(this);
activitiesPage->setLayout(layout);

int index = tabWidget()->addTab(tablePage, "tablePage");

controls, it is a QToolBar which gives me a buttons to sort the QTableView model.

- And funny is that when I will press the one of the sort buttons and the model will change, hyperlinks start to work. But the model must actually change.
- removing controls and tablePage and putting QTableView straight to TAB does not fix it.
- another funny thing that I automatically add few tabs. QtableView as first ONE. if I comment the below line mouse event works fine as well.


tabWidget()->setCurrentWidget(otherpagethenQTableView);

This gave me to think that this is some focusing problem but any of the commented lines below don't help either.


void MainWindow::currentTabChanged(int index)
{

QWidget *widget = _tabWidget->widget(index);
if (widget)
{
tabWidget()->setCurrentWidget(widget);
// if (index == 0)
// {
// Mytable()->setFocus();
// Mytable()->activateWindow();
// Mytable()->viewport()->setFocus();
// Mytable()->viewport()->focusWidget();
// Mytable()->viewport()->activateWindow();
// Mytable()->viewport()->setMouseTracking(true);
// Mytable()->viewport()->setEnabled(true);
// Mytable()->viewport()->update();

// }
}
}

AND ITS ALL ABOUT MAC

Thanks for looking.

Added after 7 minutes:

One more

I use QSortFilterProxyModel to sort a model and removing it does not help.
Removing delegates does not help either.

wysota
10th October 2011, 10:31
If you are working with QTableView, why are you reimplementing events for QTabWidget? You should enable mouse tracking for the table's viewport and set a custom delegate with mouse events handled by QAbstractItemDelegate::editorEvent(). And using stylesheets is a definite mistake here, especially that those tend to not work on mac.

migel
10th October 2011, 11:35
I don't re implementing except connecting currentTabChanged signal.

I do viewports


// if (index == 0)
// {
// Mytable()->setFocus();
// Mytable()->activateWindow();
// Mytable()->viewport()->setFocus();
// Mytable()->viewport()->focusWidget();
// Mytable()->viewport()->activateWindow();
// Mytable()->viewport()->setMouseTracking(true);
// Mytable()->viewport()->setEnabled(true);
// Mytable()->viewport()->update();

// }

Does not work

Added after 26 minutes:


bool Delegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
INFO_DEBUGME("mouse move");
if (event->type() == QEvent::MouseMove)
{
INFO_DEBUGME("mouse move");
}
}

it does not work ether, even for linux, no mouse move event here :(

Am I doing it wrong ??

wysota
10th October 2011, 11:41
Please enumerate all the problems you have with your code, it seems you are mixing more than one issue here. Please try using plain English sentences, read your post twice before submitting it, see if you were clear and provided all information about the problem. If you can, please provide a small compilable example reproducing the problem(s). Currently I don't understand what you are having problems with. I have no idea what setting mouse tracking on tables has to do with switching tabs of a tab widget and how is that related to underlining some links in some documents, setting focus, window activity or enabling or disabling some widgets.

migel
10th October 2011, 11:43
Sorry for bombarding

I have added

viewport()->setAttribute(Qt::WA_Hover);

and with that below code works "text-decoration: underline;" in mac


if (optionV4.state & QStyle::State_MouseOver) {
doc.setDefaultStyleSheet("a:hover {text-decoration: underline; cursor:pointer;}");
} else {
doc.setDefaultStyleSheet("a {text-decoration: none;cursor:pointer;}");
}


But I still have to re sort the QTableView model to get this working.

migel
10th October 2011, 19:43
You're right.

Typing too fast in rush.

Let's start from scratch.

You know my original problem. I need mouseMoveEvent(QMouseEvent *event) working without pressing a mouse button. When ever I mouse over on QTableView items it should perform some action in this overwritten function.

We know also that my QTableView exists in QTabWidget.

QTabWidget has many tabs with different QWidgets in it.

QTableView exists in the (0) index, and must be there as a first tab.

The problem I am experiencing is:

If I set to the other tab using the code below (because secondTab must default to)


TabWidget()->setCurrentWidget(secondTab);

the mouseMoveEvent function is never triggered in QTableView. It just stop working. Although if I comment setCurrentWidget out, mouseMoveEvent works as expected.

It means that when I start the app, and I will press on the FIRST tab using GUI where my QTableView exists, and try to mouse over on items, nothing happening in mouseMoveEvent function.

It looks like switching a tabs via GUI does not enable or active or focuse the QTableView or what ever is needed to have mouseMoveEvent working again.

That's why I tried what above to get this working [setMouseTracking(true)]


Hope this is clear enough, because the issue is still not for me !

Thank You for looking and helping. (really)

wysota
10th October 2011, 20:13
You know my original problem. I need mouseMoveEvent(QMouseEvent *event) working without pressing a mouse button. When ever I mouse over on QTableView items it should perform some action in this overwritten function.
You don't need mouseMoveEvent for that. Using editorEvent() is enough.


We know also that my QTableView exists in QTabWidget.

QTabWidget has many tabs with different QWidgets in it.

QTableView exists in the (0) index, and must be there as a first tab.

The problem I am experiencing is:

If I set to the other tab using the code below (because secondTab must default to)


TabWidget()->setCurrentWidget(secondTab);

the mouseMoveEvent function is never triggered in QTableView. It just stop working. Although if I comment setCurrentWidget out, mouseMoveEvent works as expected.
Please prepare a minimal compilable example reproducing the problem. I don't have a Mac, so I can't test it however maybe I'll see something in the source code.


It looks like switching a tabs via GUI does not enable or active or focuse the QTableView or what ever is needed to have mouseMoveEvent working again.
None of these properties have influence on mouse events.

migel
10th October 2011, 20:40
I have tried using editorEvent() but its not triggered at all for all platforms. I did debug on it and I have to press the mouse button to get to editorEvent().


HyperLinkDelegate::HyperLinkDelegate(QObject *parent) :
QStyledItemDelegate(parent)
{

}

QSize HyperLinkDelegate::sizeHint(const QStyleOptionViewItem & option ,
const QModelIndex & index) const
{
QStyleOptionViewItemV4 optionV4 = option;
initStyleOption(&optionV4, index);

QTextDocument doc;
doc.setHtml(optionV4.text);
doc.setTextWidth(optionV4.rect.width());
return QSize(doc.idealWidth(), doc.size().height());
}

void HyperLinkDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyleOptionViewItemV4 optionV4 = option;
initStyleOption(&optionV4, index);

QStyle *style = optionV4.widget? optionV4.widget->style() : QApplication::style();

QTextDocument doc;
QTextOption textOption;
textOption.setAlignment(Qt::AlignCenter);

doc.setDefaultTextOption(textOption);

if (optionV4.state & QStyle::State_MouseOver) {
doc.setDefaultStyleSheet("a:hover {text-decoration: underline;}");
} else {
doc.setDefaultStyleSheet("a {text-decoration: none;}");
}

doc.setHtml(optionV4.text);

// Painting item without text
optionV4.text = QString();
style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter);

QAbstractTextDocumentLayout::PaintContext ctx;

// Highlighting text if item is selected
if (optionV4.state & QStyle::State_Selected)
ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));

QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
painter->save();
painter->translate(textRect.topLeft());
painter->setClipRect(textRect.translated(-textRect.topLeft()));
doc.documentLayout()->draw(painter, ctx);
painter->restore();

}

bool HyperLinkDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
INFO_DEBUGME(" Why I am not printing on mouse over. I am printed only if you click on the item");
}


Added after 8 minutes:

according to this example http://apidocs.meego.com/1.1/core/html/qt4/itemviews-stardelegate.html

I have to set mouse tracking true for this. Unfortunately does not work for me.

wysota
10th October 2011, 20:44
I have tried using editorEvent() but its not triggered at all for all platforms.
Sure it is.


#include <QtGui>

class ItemDelegate : public QItemDelegate {
public:
ItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
protected:
bool editorEvent ( QEvent * event, QAbstractItemModel * model,
const QStyleOptionViewItem & option, const QModelIndex & index ) {
if(event->type()==QEvent::MouseMove) {
qDebug() << "Mouse event";
}
return QItemDelegate::editorEvent(event, model, option, index);
}
};

int main(int argc, char **argv) {
QApplication app(argc, argv);
QListView view;
QStringListModel model;
model.setStringList(QStringList() << "aaa" << "bbb" << "ccc");
view.setModel(&model);
view.viewport()->setMouseTracking(true);
view.viewport()->setAttribute(Qt::WA_Hover, false); // just to make sure my style doesn't set Qt::WA_Hover
view.setItemDelegate(new ItemDelegate(&view));
view.show();
return app.exec();
}

migel
10th October 2011, 21:12
Well not in my code. Probably it is the same reason why mouse even does not work in the first place. I don't have anything else, it is simple as this.

bizare

wysota
10th October 2011, 21:20
Does my code work?

migel
10th October 2011, 22:04
At least I figured why editorEvent was not working

I fixed it by removing

void QTableView::mouseMoveEvent(QMouseEvent *event)

I will checking to mac and let you know if editorEvent works there

Added after 15 minutes:

It does not work on mac :(

But again WORKS WHEN

commented out


tabWidget()->setCurrentWidget(secondPage);

migel
11th October 2011, 09:13
Yours code work.

My Does too.

On Mac works only if I remove below line


tabWidget()->setCurrentWidget(secondPage);

Strange ! isn't it ?

wysota
11th October 2011, 09:32
Please prepare a minimal compilable example reproducing the problem. Otherwise we're just chasing ghosts.

migel
14th October 2011, 15:07
Hi again

Been very busy !

Unfortunately I can't prepare any minimal code. But please don't gave up on me. I have more details about the issue.

I have noticed that QTableView does not loose mouse tracking. hasMouseTracking is always true.

When I start an app, mouse tracking does not work even hasMouseTracking is true. Then I resize a bit entire app window and this event enables my mouse.

Any thought ?

wysota
14th October 2011, 15:08
Can't help you without code to test. Without it I can only say "something in your code is wrong".