Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unexpected behavior on QWidget while the event filtering

Unexpected behavior on QWidget while the event filtering

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 4 Posters 2.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • MrKozmonM Offline
    MrKozmonM Offline
    MrKozmon
    wrote on last edited by MrKozmon
    #1

    Just i've tested the following codes on QPushButton and on QWidget and i've encountered with different behaviors. But why?

    MainWindow::MainWindow(QWidget *parent) 
            : QMainWindow(parent)
            , ui(new Ui::MainWindow)
    {
    	ui->setupUi(this);
    	ui->widget->setStyleSheet("background:blue;");
    	ui->pushButton->setStyleSheet("background:blue;");
    	ui->widget->installEventFilter(this);
    	ui->pushButton->installEventFilter(this);
    
            ...
    }
    
    bool MainWindow::eventFilter(QObject* watched, QEvent* event)
    {
    	if (watched==ui->pushButton && event->type()==QEvent::Paint)
    	{
    		// Do nothing
    		return true;
    	}
    	else if (watched==ui->widget && event->type()==QEvent::Paint)
    	{
    		// Do nothing
    		return true;
    	}
    	else
    		return QMainWindow::eventFilter(watched, event);
    }
    

    Then, the pushButton has disappeared as normally, because i've masked its paintEvent with eventFilter. But the widget has painted to blue. Why widget hasn't disappeared.

    raven-worxR 1 Reply Last reply
    1
    • E Offline
      E Offline
      euchkatzl
      wrote on last edited by
      #2

      Very interesting question.

      Because you are using stylesheets you have to filter QEvent::Polish too.

      else if (watched==widget && event->type()==QEvent::Paint || event->type()==QEvent::Polish)
      

      Alternativ you can set QPalette instead of stylesheets.

      QPalette p = widget->palette();
      p.setBrush(QPalette::All,QPalette::Background,Qt::blue);
      widget->setPalette(p);
      

      Thats the solution. But i cannot explain why the widget is painted blue without filtering the Polish event. Would be interesting for me too.

      MrKozmonM 1 Reply Last reply
      1
      • MrKozmonM MrKozmon

        Just i've tested the following codes on QPushButton and on QWidget and i've encountered with different behaviors. But why?

        MainWindow::MainWindow(QWidget *parent) 
                : QMainWindow(parent)
                , ui(new Ui::MainWindow)
        {
        	ui->setupUi(this);
        	ui->widget->setStyleSheet("background:blue;");
        	ui->pushButton->setStyleSheet("background:blue;");
        	ui->widget->installEventFilter(this);
        	ui->pushButton->installEventFilter(this);
        
                ...
        }
        
        bool MainWindow::eventFilter(QObject* watched, QEvent* event)
        {
        	if (watched==ui->pushButton && event->type()==QEvent::Paint)
        	{
        		// Do nothing
        		return true;
        	}
        	else if (watched==ui->widget && event->type()==QEvent::Paint)
        	{
        		// Do nothing
        		return true;
        	}
        	else
        		return QMainWindow::eventFilter(watched, event);
        }
        

        Then, the pushButton has disappeared as normally, because i've masked its paintEvent with eventFilter. But the widget has painted to blue. Why widget hasn't disappeared.

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @MrKozmon
        The paintEvent() handler paints most of the parts of a widget.
        But there is stuff (like the background) which is painted by Qt outside the paintEvent() handler.
        I think this is done in QWidgetPrivate::drawWidget(), which calls paintBackground().
        IIRC drawWidget() is called by the backingstore.

        The autoFillBackground property, WA_StyledBackground attribute, WA_OpaquePaintEvent attribute and WA_NoSystemBackground attribute should influence this.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        2
        • E euchkatzl

          Very interesting question.

          Because you are using stylesheets you have to filter QEvent::Polish too.

          else if (watched==widget && event->type()==QEvent::Paint || event->type()==QEvent::Polish)
          

          Alternativ you can set QPalette instead of stylesheets.

          QPalette p = widget->palette();
          p.setBrush(QPalette::All,QPalette::Background,Qt::blue);
          widget->setPalette(p);
          

          Thats the solution. But i cannot explain why the widget is painted blue without filtering the Polish event. Would be interesting for me too.

          MrKozmonM Offline
          MrKozmonM Offline
          MrKozmon
          wrote on last edited by
          #4

          @euchkatzl First, as i can see, QWidget not even have any member function starts with "polish", so, there is no polishEvent for QWidget.
          QWidget All Members List

          On the other hand, even with QPalette, the result is same, pushButton disappeared, widget not.

          raven-worxR kshegunovK 2 Replies Last reply
          0
          • MrKozmonM MrKozmon

            @euchkatzl First, as i can see, QWidget not even have any member function starts with "polish", so, there is no polishEvent for QWidget.
            QWidget All Members List

            On the other hand, even with QPalette, the result is same, pushButton disappeared, widget not.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @MrKozmon
            not all events have an own event handler method. These are just here for convenience purposes to help keep the code clean.

            All events go through the widgets standard event() handler, whcih then forwards it to the specific event handlers if available.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            2
            • MrKozmonM MrKozmon

              @euchkatzl First, as i can see, QWidget not even have any member function starts with "polish", so, there is no polishEvent for QWidget.
              QWidget All Members List

              On the other hand, even with QPalette, the result is same, pushButton disappeared, widget not.

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by
              #6

              @MrKozmon
              Here's a pretty extensive list of the types of events passed around. As you can see most of those have no dedicated handler functions (just as @raven-worx pointed out).

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              1
              • MrKozmonM Offline
                MrKozmonM Offline
                MrKozmon
                wrote on last edited by MrKozmon
                #7

                You're right and thanks for your answers. I've solved the problem with changing QEvent::Paint with QEvent::Polish. Then, as normally, QWidget disappeared.

                else if (watched==ui->widget && event->type()==QEvent::Polish)
                {
                    // Do nothing
                    return true;
                }
                

                Because as @euchkatzl pointed out, sytleSheets handled in Polish event for QWidget. But for QPushButton this not work. For QPushButton, styleSheets handled in just Paint event, not in Polish event. So the following not work on QPushButton:

                if (watched==ui->pushButton && event->type()==QEvent::Polish)
                {
                	// Do nothing
                	return true;
                } //And pushButton painted to blue as abnormally.
                

                But what's the difference between this two widgets. Whereas QPushButton derivered from QWidget, right. And the second question is that, when i set a Palette to widget, i can't mask the painting event anymore in both of Polish and Paint events filter. So this is not work anymore:

                else if (watched==ui->widget && (event->type()==QEvent::Polish || event->type()==QEvent::Paint))
                {
                	// I can't catch the painting anymore
                	return true;
                }
                

                Where the painting actually happened in when i used pallets. And why every painting events just not happening only on paintEvent. How can i know all the different paint handlers in different situations. Why it's not just paintEvent function. Isn't that a worse programming model, and also i couldn't even found a proper explanation(documentation) for this, "Where the painting actually happening outside paintEvent for different situations."

                Anyway, thanks everybody.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved