无限极制度的劣势:How to implement QListWidget slide animation

来源:百度文库 编辑:偶看新闻 时间:2024/04/29 16:03:16


How to customize QListWidget with different highlight bar and spacing

up vote1down votefavoriteshare [fb]share [tw]

I'm working on an application that needs to have a menu on the left side of the screen containing multiple items (text). The only items I want to be visible are the actual text and the highlight bar. I would also like to modify the highlight bar so that: a. I can animate it, and slide it from one selection to the next b. I can use a custom pixmap with rounded corners instead of the default highlight color

I've tried using a QListWidget and stylesheets and had some success, but I don't believe it's possible to round the corners of my highlight bar using this method. I'm also not sure I can animate the movement of the bar from one item to the next:

preset_list_view->setStyleSheet("QListView {color: rgb(230, 230, 230); background-color: rgba(0,0,0,0); border-style: none} QListView::item:selected {background-image: url(:/ui_resources/elements-preset_select/highlight_bar_270x30-black_bg.bmp)}");

I've looked all over online and not found much. There is some mention of modifying the delegate of the QListWidget, but the descriptions have been vague. I'm also not sure if this would solve my animation problem.

Any ideas?

qt qlistwidgetlink|improve this questionasked Sep 1 at 18:31Marlon Smith
395
44% accept rateThere is something close to what you want in the QML examples (QtSDK/Examples/4.7/declarative/modelviews/listview/highlightranges/qml/highligh??tranges.qml, that you run withqmlviewer). Basically it's a list with a animated transparent selection indicator which moves smoothly. – alexisdm Sep 14 at 2:19Was this post useful to you?     

2 Answers

activeoldestvotesup vote2down vote

You can place a semi transparent inert widget on top of the QListWidget, and animate it when the selection changes. But you also need a delegate to disable the normal selection indicator.

A working example:

#include 
#include
#include
#include

class RemoveSelectionDelegate : public QStyledItemDelegate {
public:
    RemoveSelectionDelegate(QObject *parent = 0)
        : QStyledItemDelegate(parent) {
    }

    void paint(QPainter *painter, const QStyleOptionViewItem &option,
               const QModelIndex &index) const {
        // Call the original paint method with the selection state cleared
        // to prevent painting the original selection background
        QStyleOptionViewItemV4 optionV4 =
            *qstyleoption_cast(&option);
        optionV4.state &= ~QStyle::State_Selected;
        QStyledItemDelegate::paint(painter, optionV4, index);
    }
};

class ListWidget : public QListWidget {
    Q_OBJECT
public:
    ListWidget(QWidget *parent = 0)
        : QListWidget(parent)
        , selectionFrame(this)
        , animation(&selectionFrame, "geometry") {
        // Create a semi-transparent frame that doesn't interact with anything
        selectionFrame.setAttribute(Qt::WA_TransparentForMouseEvents);
        selectionFrame.setFocusPolicy(Qt::NoFocus);

        // You can put your transparent image in that stylesheet
        selectionFrame.setStyleSheet("background: solid rgba(0, 0, 125, 25%);");
        selectionFrame.hide();
        animation.setDuration(250);
        animation.setEasingCurve(QEasingCurve::InOutBack);

        connect(this,
                SIGNAL(currentItemChanged(QListWidgetItem*, QListWidgetItem*)),
                SLOT(updateSelection(QListWidgetItem*)) );        
        setItemDelegate(new RemoveSelectionDelegate(this));
    }

private slots:
    void resizeEvent(QResizeEvent *e) {
        QListWidget::resizeEvent(e);
        updateSelection(currentItem());
    }

    void updateSelection(QListWidgetItem* current) {
        animation.stop();
        if (!current) {
            selectionFrame.hide();
            return;
        }
        if (!selectionFrame.isVisible()) {
            selectionFrame.setGeometry(visualItemRect(current));
            selectionFrame.show();
            return;
        }
        animation.setStartValue(selectionFrame.geometry());
        animation.setEndValue(visualItemRect(current));
        animation.start();
    }
private:
    QFrame selectionFrame;
    QPropertyAnimation animation;
};
link|improve this answeredited Sep 2 at 0:57
answered Sep 1 at 22:30alexisdm
3,222210Thanks alexisdm, I will give that a go (after I spend a few minutes trying to wrap my head around it!). I'm a little disappointed that Qt hasn't provided this functionality in an easier way, although who am I to complain too much about completely free software? – Marlon Smith Sep 2 at 17:07feedbackup vote1down vote

So if its just text then why not have a QDockwidget with QLabels.

For example, take a look at the 'Qt Designer's 'Widget Box' on the left, you can drag that and place it on the top. Is that what you are looking for?

You can move the dockwidget as you want.

link|improve this answeranswered Sep 1 at 19:03blueskin
1,396210That's not a terrible idea, although I should have mentioned that I need to be able to easily add/remove items from the list, and it needs to be scrollable, as well as emitting a signal when an item is selected. I also need to be able to select the next or previous item in the menu when I receive a signal (from a hardware button). A QListWidget nicely includes all this functionality, so it seemed easiest to just modify it for what I need. – Marlon Smith Sep 1 at 20:23Do you have an example or an image of what your are trying to achieve? – blueskin Sep 1 at 20:49Hi blueskin, I don't think I'm able to provide an actual image of what I'm doing since it's for a client (although I believe it is going to be open source in the future). Picture a QListBox where the only things visible are the items in the list, the selection bar is a custom bitmap, and the selection bar slides from one item to the next. If the number of items exceeds the size of the screen, the list will scroll as the selected item changes. – Marlon Smith Sep 2 at 17:02I mean QListWidget, not QListBox. – Marlon Smith Sep 2 at 17:08ok then basically you cant create a widget that animates and does all the stuff you want and put it in the list widget using setItemWidget. doc.qt.nokia.com/latest/qlistwidget.html#setItemWidget – blueskin Sep 2 at 18:46