[SOLVED] QWidget - make a part transparent for mouse event,



  • Hi,

    I have the current custom QWidget "RepeatWidget":
    https://www.dropbox.com/s/e7z7ge6qia5z7z6/repeatWidget_transparent.png

    This widget is shown on a top of a QTableView.
    Because the first column of the QTableView change the mouse cursor to a hand cursor, I need to RepeatWidget to be transparent for mouse event. But by doing that, the ComboBox and the button on the far right are no more usable.

    Is it possible to set part of a QWidget transparent for mouse event and other not transparent? Any hack possible here?
    Thanks!

    RepeatWidget code :
    @RepeatWidget::RepeatWidget(RepeatData *data, QWidget *parent) :
    QWidget(parent),
    ui(new Ui::RepeatWidget)
    {
    ui->setupUi(this);

    //    ui->frame_left->setAttribute(Qt::WA_TransparentForMouseEvents);  /// not working on QFrame
    setAttribute(Qt::WA_TransparentForMouseEvents);  /// Will set for the whole widget, I only need part of it...
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::FramelessWindowHint );
    
    
    this->data = data;
    ui->comboBox_repeat->setCurrentText(QString::number(data->getNumberRepeat()));
    

    }
    @


  • Lifetime Qt Champion

    Hi,

    AFAIK, you can't, however you could setup the QTableView has an eventFilter for the Repeat widget so you can handle the mouse move event over the first column.

    Hope it helps



  • Thanks, I think i'll have a read of this :
    http://qt-project.org/doc/qt-4.8/eventsandfilters.html
    will post code when I get it :)



  • Hey SGaist,

    EventFilter are really interesting and powerful, I will use them more often.

    I have set up my RepeatWidget events to be filtered by my tableView eventFilter. But it seems my widget only trigger "Enter" and "Leave" events. I don't have the mouseMoveEvent by default?

    Thanks!

    Here is the code :

    Set up object to use eventFilter:
    @ RepeatWidget *repeatWidgetCopy = new RepeatWidget(repData, ui->tableView->viewport());
    repeatWidgetCopy->setMouseTracking(true);
    repeatWidgetCopy->installEventFilter(ui->tableView);

    ui->tableView->horizontalHeader()->setMouseTracking(true);
    ui->tableView->verticalHeader()->setMouseTracking(true);
    connect(ui->tableView, SIGNAL(entered(QModelIndex)), ui->tableView, SLOT(setCursor(QModelIndex)) );
    ui->tableView->horizontalHeader()->installEventFilter(ui->tableView);
    ui->tableView->verticalHeader()->installEventFilter(ui->tableView);@
    

    eventFilter:
    @bool TableViewInterval::eventFilter(QObject *watched, QEvent *event) {

    qDebug() << "watched object" << watched << "event:" << event << "eventType" << event->type();
    
    
    /// Change cursor to normal when hovering on Headers;
    if(qobject_cast<QHeaderView*>(watched) != nullptr && event->type() == QEvent::HoverMove)
    {
        qDebug() << "HoverMove" << watched;
        QApplication::setOverrideCursor(Qt::ArrowCursor);
    }
    
    else if (watched->objectName() == "RepeatWidget")
    {
        qDebug() << " got here now Repeat_Widget" << event->type() << event;
        if (event->type() == QEvent::MouseMove) {
            qDebug() << "RepeatWidget Mouse move now!";
            /// Check position to see if we are at column 0, if so, change cursor
            QMouseEvent *mouseMoveEvent = static_cast<QMouseEvent*>(event);
            QPoint pos = mouseMoveEvent->pos();
            qDebug() << "pos" << pos;
            //        QModelIndex index = ui->tableView->indexAt(pos);
            //        int row = index.row();
            //        if (index.isValid())
            //        {
            //            qDebug() << "index is" << row;
    
        }
    
    }
    
    return false;
    

    }
    @



  • Problem seems to be with the custom QWidget that trigger MouseMove only once when it enter the Widget, but doesn't trigger more when I move inside the Widget itself

    log :
    watched object RepeatWidget(0x3d3c510, name = "RepeatWidget") event: QMouseEvent(MouseMove, 0, 0, 0) eventType 5
    RepeatWidget Mouse move now!
    pos QPoint(516,73)


  • Lifetime Qt Champion

    mouseMove event is only called if you are keeping a mouse button pressed. The other way to get the mouse move event continuously is to use setMouseGrabEnabled but have a look at the documentation before using it



  • Yo SGaist,
    Been lazy, I redesigned a new QWidget containing 2 QWidgets, one of the left with transparent mouse event and the one of the left with the controls can still get the mouse events:

    Here it is if it can help anyone:
    https://www.dropbox.com/s/66mp8rj9g4ybtw0/interfaceRepeat22.png

    Only thing to fix is a small gap in the border of the two QWidget frame, even with 0 margin they are not close enough, will investigate..
    thanks for the help!


  • Lifetime Qt Champion

    Did you also set the spacing to 0 ?



  • Yeah all the Layout have 0 margins and spacing, there must be another element that factor in.. it's like a 1mm margin, the QWidget are not touching but almost.. weird

    I tried negative margin on the layouts but not working so far,
    Thanks


  • Lifetime Qt Champion

    The space doesn't mean the widget's not right. Are you giving him a fixed size ?



  • The SizePolicy is set to minimumExpending (horizontal and vertical), not fixed.

    The size is set dynamicly at run time when user press a button this is called :
    Here it is :

    @ RepeatData *repData = new RepeatData(id, firstRow, lastRow, numberRepeat);
    RepeatWidget *repeatWidgetCopy = new RepeatWidget(repData, ui->tableView->viewport());
    repeatWidgetCopy->move(rectCompleteSelection.topLeft());
    repeatWidgetCopy->resize(rectCompleteSelection.size().width() + 190, rectCompleteSelection.size().height());
    repeatWidgetCopy->show();@

    Also some attribute that may interest you :

    @ ui->widget_left->setAttribute(Qt::WA_TransparentForMouseEvents);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::FramelessWindowHint );@

    Except that, it's a standard QWidget containing 2 QWidget that have a stylsheet with a border-color. Thanks!


  • Lifetime Qt Champion

    Can you show the left widget not transparent just to see how far it goes ?



  • Hmm not sure what you mean, the widget is transparent only for mouse event, both widget just have a border, no background
    https://www.dropbox.com/s/66mp8rj9g4ybtw0/interfaceRepeat22.png

    Thanks


  • Lifetime Qt Champion

    Sorry, I meant translucent



  • yeah this flag doesn't do much actually, same thing commented or not :/



  • It's not a major bug, I may change the design to show a verital doted line between both widget, I'll see if I can't fix it i'll change it, thanks



  • To have two QFrame without space between them:
    this code worked (added 0px border because default is 1px I think, that was the problem!)

    @#frame_border_left {

    border-left : 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));
    border-top: 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));
    border-bottom: 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));
    border-right : 0px;

    }

    #frame_border_right {

    border-left : 0px;
    border-right : 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));
    border-top: 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));
    border-bottom: 4px solid qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(7,0,62,255), stop:1 rgba(13, 0, 158, 255));

    }@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.