tags:

views:

1265

answers:

3

I would like to use a stylesheet :focus pseudo-state to control the representation of the Tree view's focus state. Using the following stylesheet works well, except that the Qt system still draws it's own focus rect. How do I ask Qt to not draw the focus rect, while still being able to focus the control for keyboard input?

QTreeView {
    background: #505050;
    border: 1px solid;
    border-radius: 10px;
}

QTreeView:focus { 
    border: 2px groove;
}
A: 

I don't know an immediate answer to your question, but here is a code snippet for a tree view I customized with qt style sheets. Maybe it can help you out in some way. I believe the show-decoration-selected property is what enables the default focus draw (could be wrong, been a while since I fooled with it)

QString treeview_ss = "QTreeView { color: white; background: black; }" +
        QString("QTreeView { show-decoration-selected: 0; }") +
        QString("QTreeView::item:selected { border: 1px solid grey; }") +
        QString("QTreeView::item:selected:!active { color: white; border: 1px solid grey; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #000000, stop: 1 grey); }") +
        QString("QTreeView::item:selected:active { border: 1px solid grey; background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #000000, stop: 1 grey); }") +
        QString("QTreeView::item:hover { border: 1px solid grey; }") +
JimDaniel
+1  A: 

You can use setItemDelegate method of the treeview to setup custom paint procedure for your treeview items. In the paint method you of the deligate you can remove QStyle::State_HasFocus style from the items options and execute the base painting routine. Below is an example, sorry it's c++.

...
    NoFocusDelegate* delegate = new NoFocusDelegate();
    ui->treeView->setItemDelegate(delegate);
...

class NoFocusDelegate : public QStyledItemDelegate
{
protected:
    void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
};

void NoFocusDelegate::paint(QPainter* painter, const QStyleOptionViewItem & option, const QModelIndex &index) const
{
    QStyleOptionViewItem itemOption(option);
    if (itemOption.state & QStyle::State_HasFocus)
        itemOption.state = itemOption.state ^ QStyle::State_HasFocus;
    QStyledItemDelegate::paint(painter, itemOption, index);
}

update0: removing QFocusFrame from being drown over a TReeView using custom QStyle object. Below is an example of custom QMotifStyle style descendant (I guess in your case I guess it should be a QMacStyle descendant) which is applied to the application object. It doesn't do any frame rectangle painting whenever it detects a qtreeview widget

class MyStyle1 : public QMotifStyle
{
public:
    MyStyle1()
    {
        //???
    }

    void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget = 0 ) const
    {
        if (element==CE_FocusFrame)
        {
            const QFocusFrame* frame = qobject_cast<const QFocusFrame*>(widget);
            if (frame && frame->widget())
            {
                QTreeView* treeView = qobject_cast<QTreeView*>(frame->widget());
                if (treeView)
                {
                    qDebug() << "no CE_FocusFrame for QFocusFrame over QTreeViews";
                    return;
                }
            }
        }
        QMotifStyle::drawControl(element, option, painter, widget);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QCDEStyle style;
    a.setStyle(new MyStyle1());
    //a.setStyle(new QMotifStyle());
    MainWindow w;
    w.show();
    return a.exec();
}

hope this helps, regards

serge_gubenko
@serge, thanks for the great info on ItemDelegates. The first problem I'm having is a giant focus blue rect around the entire TreeView I've styled.
Shane Holloway
I've uploaded a screenshot to illustrate: http://techgame.net/~shane/temp/QTreeView-stylesheets.png
Shane Holloway
I first thought you want to remove focus rects drown over tree view items, but I guess what you see highlighted is QFocusFrame drown over your control by the style used for your application. It looks like QMacStyle but I can be wrong here. I also can't check it on my laptop as I'm running ubuntu. Pls, see if an update I've made to the original post would work for you
serge_gubenko
@serge, it turns out to be a Mac-only problem. tree.setAttribute(Qt.WA_MacShowFocusRect, 0)Thanks for your help!
Shane Holloway
+2  A: 

The focus rect around the QTreeView widget itself turns out to be a Mac styling feature. This turns it off per widget:

tree.setAttribute(Qt.WA_MacShowFocusRect, 0)
Shane Holloway