How can I determine the cursor is hang on a item(QStandardItem)'s checkBox?



  • I use a QTableView that used an QStandardItemModel populated with QStandardItems .and the first column items is checkabled.(with checkBox preceding).

    Now I want to know if the mouse click in current-pos whether can click the checkBox and change it's checkState other than a normal clicked() even in advance.(means before the click even be sent);

    I know the checkState change will signal the ItemChange(item) of Model while normal clicked even not. So don't consider that answer.

    may I need know is the checkBox is rect and pos before the click happends.The key is before the click happend.

    Any advice will be welcome!

    thanks!
    regards



  • I am not sure I did get you right, otherwise let us know.
    Are you looking for a function that gives you the current focus like QApplication::focusWidget() ?
    If you let update the focus by the current mouse position this should work.



  • no! I'm not!
    QTableView definitely has the focus.
    what's I want is the if a mouse-press even happened,I can determine whether this click can lead a item's checkState changed.
    (click on the checkBox of an item) in case of not by the ItemChanged() or dataChange() signal.



  • QWidget * QWidget::childAt(int x, int y) const
    Returns the visible child widget at the position (x, y) in the widget's coordinate system. If there is no visible child widget at the specified position, the function returns 0.

    QPoint QCursor::pos() [static]
    Returns the position of the cursor (hot spot) of the primary screen in global screen coordinates.

    QPoint QWidget::mapFromGlobal(const QPoint & pos) const
    Translates the global screen coordinate pos to widget coordinates.

    and check if QWidget's metaobject class name is QCheckBox ... so you could know in advance the current state of a check box

    hope it helps a little!


  • Moderators

    [quote author="NicuPopescu" date="1386601306"]QWidget * QWidget::childAt(int x, int y) const
    Returns the visible child widget at the position (x, y) in the widget's coordinate system. If there is no visible child widget at the specified position, the function returns 0.
    [/quote]
    This wont work here. Since there are no QWidget instances at all involved for checkboxes in item views! They are purely drawn by the style. So the only chance to do this is only via the style:
    @
    bool MyTableView::checkIfPosIsInCheckbox(const QPoint & pos)
    {
    QStyle style = this->style();

    QStyleOptionViewItemV4 option;
    this->initStyleOption(&option, this->indexAt(pos) );
    
    QRect checkBoxIndicatorRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, option, this);
    return checkBoxIndicatorRect.contains(pos);
    

    }
    @
    I guess the checkBoxIndicatorRect is in viewport coordinates (not sure though). You need to check that, since i wrote this code out of my mind and haven't tested it.
    Thus your QPoint parameter needs also to be in viewport coordinates and most probably the the translation from the scrollbars also need to be considered to make this code work.



  • raven-worx you're right!

    I think it is even better so, since it would be suffice just to enter the item rect not merely to be hover the drawn checkbox's rect:

    1. QModelIndex QTableView::indexAt(const QPoint & pos) const [virtual]
      Reimplemented from QAbstractItemView::indexAt().

    2.QVariant QModelIndex::data(int role = Qt::DisplayRole) const

    3.inline Qt::CheckState checkState() const
    { return static_castQt::CheckState(data(Qt::CheckStateRole).toInt()); }

    ... point 3. is from qtablewidget source



  • [quote author="raven-worx" date="1386602726"]
    This wont work here. Since there are no QWidget instances at all involved for checkboxes in item views! They are purely drawn by the style. So the only chance to do this is only via the style:
    @
    bool MyTableView::checkIfPosIsInCheckbox(const QPoint & pos)
    {
    QStyle style = this->style();

    QStyleOptionViewItemV4 option;
    this->initStyleOption(&option, this->indexAt(pos) );
    
    QRect checkBoxIndicatorRect = style->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, option, this);
    return checkBoxIndicatorRect.contains(pos);
    

    }
    [/quote]
    first Thanks very much,this is right and relly help me .but little problem.
    My widget is subclass of QTableview.but* this->initStyleOption()* is not one of the member of QTableview. My QT is 4.7.3.

    Any hint?


  • Moderators

    yes sorry my fault.
    It's a member of QStyledItemDelegate. You need to move the implementation to your delegate implementation and call it from there.



  • thanks very much.
    I have got it!


Log in to reply
 

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