Как настроить QListWidget с другой полосой выделения и интервалом
Я работаю над приложением, которое должно иметь меню в левой части экрана, содержащее несколько элементов (текст). Единственные элементы, которые я хочу видеть, - это текст и строка выделения. Я также хотел бы изменить строку выделения так, чтобы: a. Я могу оживить его и переместить из одного выбора в другой. B. Я могу использовать пользовательское растровое изображение с закругленными углами вместо цвета подсветки по умолчанию
Я пытался использовать QListWidget и таблицы стилей и добился некоторого успеха, но я не верю, что с помощью этого метода можно закруглить углы моей выделенной панели. Я также не уверен, что смогу оживить движение бара от одного элемента к другому:
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)}");
Я просмотрел все онлайн и не нашел много. Есть некоторые упоминания об изменении делегата QListWidget, но описания были расплывчатыми. Я также не уверен, решит ли это мою проблему с анимацией.
Есть идеи?
2 ответа
Вы можете разместить полупрозрачный инертный виджет поверх QListWidget и анимировать его при изменении выделения. Но вам также нужен делегат, чтобы отключить индикатор нормального выбора.
Рабочий пример:
#include <QListWidget>
#include <QFrame>
#include <QPropertyAnimation>
#include <QStyledItemDelegate>
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<const QStyleOptionViewItemV4 *>(&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;
};
Так что, если это просто текст, то почему бы не иметь QDockwidget с QLabels.
Например, взгляните на "Окно виджетов" Qt Designer'а слева, вы можете перетащить его и поместить сверху. Это то, что вы ищете?
Вы можете перемещать док-виджет как хотите.