QScrollBar on mouse hover - c++

I want to change QScrollBar style on mouse hover. I have tried to get it working by adding eventFilter, but it doesn't work.
Code:
qApp->installEventFilter(this);
bool Test::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::Scroll) {
QScrollEvent *scrollEvent = static_cast<QScrollEvent*>(event);
if (scrollEvent->scrollState() == QScrollEvent::Enter) {
qDebug() << "Enter";
this->setStyleSheet("QScrollBar:vertical {width: 20px;}");
}
if (scrollEvent->scrollState() == QScrollEvent::Leave) {
qDebug() << "Leave";
this->setStyleSheet("QScrollBar:vertical {width: 12px;}");
}
}
return QObject::eventFilter(object, event);
}
How can I do this?

The correct events to handle in your event filter would actually be QEvent::Enter, and QEvent::Leave. QScrollEvent is used when scrolling actually occurs, that's why it was not triggered.
You can also probably directly use stylesheets with the :hover attribute.

Related

Qt: eventFilter does not recieve KeyPress when QCompleter is shown

I have an subclassed QPlainTextEdit called Editor. The editor contains an object used to suggest text, called a Suggester. The user can press a button from the Suggester to show a QCompleter, the activeCompleter.
I need to mess with the activeCompleter when KeyPress events come in from the Editor, so in Suggester, I create an eventFilter and install it to the passed in Editor instance.
When the activeCompleter is not shown, the eventFilter receives the KeyPress events as expected. However, when the activeComplter is shown via activeComplter->complete(), the eventFilter does not recieve KeyPress events (the editor behaves however).
I don't understand why this is. The QCompleter is not a widget. The Editor retains focus. I do not intercept events or keys anywhere else.
Why is my eventFilter not receiving KeyPress events?
relevant code...
Editor::Editor(QWidget *parent) : QPlainTextEdit(parent){
suggester = new Suggester(this);
}
Suggester::Suggester(Editor* editor){
this->editor = editor;
editor->installEventFilter(this);
}
bool Suggester::eventFilter(QObject *obj, QEvent *event){
qDebug()<< "event filter of type " << event->type() << " from " << obj;
return false;
}
It seems that your eventFilter member is incomplete. You have to filter the QEvent:KeyPress event as follows:
bool Suggester::eventFilter(QObject *obj, QEvent *event)
{
if (obj == textEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return Suggester::eventFilter(obj, event);
}
}

How can you still use the functionalities of a widget if set to Transparent for Mouse Events?

I have a widget on top of my mainwindow, more like and Advertisement Banner. It is preventing the user from using some functionalities behind it so I set it to
setAttribute( Qt::WA_TransparentForMouseEvents );
But that specific ad banner has 2 buttons, and if it set as 'transparent', they can't be used obvoiusly. My question is that, how can I still use the button functionalities inside the banner of it set to transparent for mouse events?
It looks like this:
Made a solution using the Mouse Events of the said Banner Widget:
void advertisement::mouseMoveEvent(QMouseEvent *event)
{
qDebug()<< event->button();
if (isRightBtn)
{
this->setAttribute(Qt::WA_TransparentForMouseEvents);
main->_IsCamRotate = true;
main->triggerMouseMove(event);
}
}
void advertisement::mousePressEvent(QMouseEvent *event)
{
qDebug()<< event->button();
switch(event->button())
{
case Qt::MouseButton::RightButton:
isRightBtn = true;
break;
}
}
void advertisement::mouseReleaseEvent(QMouseEvent *event)
{
if (!this->rect().contains(event->pos()) && event->button() == Qt::MouseButton::RightButton)
{
main->triggerMouseRelease(event);
isRightBtn = false;
this->setAttribute(Qt::WA_TransparentForMouseEvents, false);
}
}

how to take screenshot with Paint event (WM_Paint) in QT

i'm trying to take screenshot with Paint event (WM_Paint) event in QT but i dont know how,
i used this code to take screenshot but it is not really good for do this
it must do screenshot when some changes in desktop not take screenshot every 1000 ms with timer
void MainWindow::shootScreen()
{
originalPixmap = QPixmap(); // clear image for low memory situations
// on embedded devices.
originalPixmap = QPixmap::grabWindow(QApplication::desktop()->winId());
//emit getScreen(originalPixmap);
updateScreenshotLabel();
}
void MainWindow::updateScreenshotLabel()
{
this->ui->label_2->setPixmap(originalPixmap.scaled(this->ui->label_2- >size(),
Qt::KeepAspectRatio,
Qt::SmoothTransformation));
}
Use QObject::installEventFilter on the widgets you are interested in, then check for the proper events. For example, in your MainWindow ui initialization:
void MainWindow::yourUiInitFunc()
{
exampleWidget = new QWidget;
...
exampleWidget->installEventFilter(this);
...
}
Then re-implement eventFilter:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == exampleWidget && event->type() == QEvent::KeyPress)
shootScreen();
return QMainWindow::eventFilter(obj, event);
}
tank you Jon Harper your codes was useful but i changed somethings there
your code just work when some key press event on my project form but i added paint method to your if and now it work on windows events too
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == this && QEvent::Paint == event->type()) {
shootScreen();
}
return false;
}

Right click on QTreeView item

I want to generate the right click menu from the entry of a QTreeView. Currently I tried this, but I don't want the whole treeView to generate the right click and then me to filter the position on which the mouse is. I want that the signal to be generated from the entry.
connect(mtreeView, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(showContextMenu(const QPoint&)));
Thanks!
Method 1
It is better to use the ContextMenuEvent rather than MouseReleaseEvent as it is a more portable way to trigger the context menu, will support accessibility on certain platforms, etc... The right click is not the only way to open a context menu.
If you do not want to subclass QTreeView , install an event handler from the main window:
ui->myTreeView->installEventFilter(this);
Then handle the event in the main window filterEvent
bool MainWindow::eventFilter(QObject *target, QEvent *event)
{
if (target == ui->myTreeView)
{
QContextMenuEvent* m = dynamic_cast<QContextMenuEvent*>(event);
if (event->type() == QEvent::ContextMenu && e!=0)
{
//Create context menu here
return true;
}
}
return false;
}
Method 2
Change the context menu mode to a signal:
ui->myTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->myTreeView, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(treeCustomMenu(QPoint)));
Then implement your slot:
void MainWindow::treeCustomMenu(const QPoint & pos)
{
//Implement your menu here using myTreeView->itemAt(pos);
}
What I do is to override mouseReleaseEvent and check manually.
void MyTreeView::mouseReleaseEvent(QMouseEvent *e) {
if (e->button() == Qt::RightButton) {
QTreeWidgetItem *item = itemAt(e->pos());
if (item) {
QMenu m;
m.addAction("hello");
m.addAction("world");
QAction *selected = m.exec(mapToGlobal(e->pos()));
if (selected) {
qDebug() << "selected" << selected->text();
}
}
} else {
QTreeView::mouseReleaseEvent(e);
}
}
What you mean by the entry is not represented by a QObject in Qt. Only the item model is a QObject, but the individual tree nodes are not QObjects in Qt item/view system.
Therefore, they cannot emit any signal

QtWebkit resolving event dispatcher

i'm playing around with QtWebkit lately and i was wondering if it is possible to resolve the element displayed in the QWebView which is responsible for an event, e.g. a MouseEvent.
I've installed an EventFilter function at the WebView Object with a function like this:
bool WebKitManager::eventFilter(QObject *obj, QEvent *event)
{
if(event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if(mouseEvent->button() == Qt::LeftButton)
{
// what now?!
}
}
return false;
}
Is there any way to get a reference to the clicked element that is displayed in the QWebView? As far as i can tell, the passed QObject equals the WebView object and the event doesn't seem to hold reference to its dispatcher.
Since i'm far away from beeing a c++ professional i sincerely hope i missed something and you guys can help me out :)
Thanks in advance
Timo
I believe what you could do is:
cast object parameter to QWebView
get QWebFrame under mouse via vebView->page()->frameAt() method
use hitTestContent method of the returned frame to detect the element for the given mouse position
Below is an example:
bool WebKitManager::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::MouseButtonRelease)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
QWebView *view = dynamic_cast<QWebView*>(object);
QPoint pos = view->mapFromGlobal(mouseEvent->globalPos());
qDebug() << view->url().toString() << " clicked at x:" << pos.x() << " y:" << pos.y();
QWebFrame *frame = view->page()->frameAt(mouseEvent->pos());
if (frame!=NULL)
{
QWebHitTestResult hitTestResult = frame->hitTestContent(pos);
qDebug() << "element" << hitTestResult.element().localName();
}
}
}
return false;
}
hope this helps, regards
Use qobject_cast instead of dynamic_cast.