あなたがやろうとしていることは、qtについて私を悩ますものの完璧な例です - Qtのデザイナーが考えていないグラフィカルな効果があれば、それを自分で作成するのは苦痛です。とにかくあきらめることで終わります。
私はあなたの心に小さな画面(携帯電話かタブレット?)でやっていると思うので、この問題を解決する方法は他にありません。私はここにしようとしています何
はハックですが、そうでなければ、おそらくそれらのいくつかの不足している詳細情報を追加するために全体のスクロールバーを自分で書き換えなければならないでしょう。私の提案は次のとおりです。
#ifndef MYSCROLLBAR_H
#define MYSCROLLBAR_H
#include <QScrollBar>
class MyScrollBar : public QScrollBar
{
Q_OBJECT
public:
explicit MyScrollBar(QWidget *parent = 0);
protected:
void showEvent (QShowEvent * event);
signals:
public slots:
void updateMask();
};
#endif // MYSCROLLBAR_H
そしてmyscrollbar.cppに
#include "myscrollbar.h"
#include <QPaintEvent>
#include <QRegion>
#include <QStyleOptionSlider>
MyScrollBar::MyScrollBar(QWidget *parent) :
QScrollBar(parent)
{
connect(this, SIGNAL(valueChanged(int)), this, SLOT(updateMask()));
}
void MyScrollBar::updateMask(){
QStyleOptionSlider opt;
initStyleOption(&opt);
QRegion r(style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this));
r+= style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarAddLine, this);
r+= style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSubLine, this);
setMask(r);
}
void MyScrollBar::showEvent (QShowEvent * event){
QScrollBar::showEvent(event);
updateMask();
}
このようなスクロールが、それは非重要な部分だのいずれかに(視覚的にもイベント的に)透明になります。それはまだそれの下に横たわるウィジェットにいくつかのアーティファクトを作り出します - 私はsetMask()
がこのように使用されることは決してないと思います。これを緩和するには、valueChanged()
シグナルをリストウィジェットのビューポートのupdate()
スロットに接続します。これは私のおもちゃの例でうまくいきましたが、カスタムウィジェットをあなたのリストに埋め込むと、それに対処することは耐え難くなるかもしれません。さらに複雑なアプリケーションの場合、特にモバイルプラットフォーム向けに記述する場合は、パフォーマンス上の問題につながる可能性があります。
QScrollBarクラス全体を "fork"して、単にpaintEventを変更してSC_Allよりも少ないsubControlを使用することもできます。コンストラクタにsetAttribute(Qt::WA_OpaquePaintEvent, false);
を追加すると、視覚的に透明になります。次に、リストウィジェットのビューポート(ビューのカスタムウィジェットと再び、トラブル)にマウスイベント(重要な何かを打っていない場合)にも転送する必要があります。
残っているのは、リストビューとスクロールバーの両方を正しい位置に置く独自のレイアウトクラスを作成することです(または手動で配置すること).QStackedLayoutはうれしいですが、1つのレイヤだけが表示される時間 - 明らかに私たちが探しているものではありません。
最後のステップでは、実際のスクロールの効果を得るために、デフォルトのスクロールバーの表示をオフにし、既定(見えない)スクロールバーの信号/スロットをスクロールバーのスロット/信号に接続します。
まもなくこれを行うにはコードのLOTが必要です。そんな単純な効果が本当に価値があると確信していますか?
** EDIT:**
私は互いの上にウィジェットを積み重ねるためのレイアウトクラスを作成する - この質問は私に最終的にそれを行うための動機を与えた;)
#ifndef STACKLAYOUT_H
#define STACKLAYOUT_H
#include <QLayout>
class StackLayout : public QLayout
{
Q_OBJECT
public:
StackLayout();
explicit StackLayout(QWidget *parent);
~StackLayout();
void addItem (QLayoutItem * item);
int count() const;
Qt::Orientations expandingDirections() const;
bool hasHeightForWidth() const;
int heightForWidth (int w) const;
QLayoutItem * itemAt (int index) const;
bool isEmpty() const;
QSize maximumSize() const;
int minimumHeightForWidth (int w) const;
QSize minimumSize() const;
void setGeometry (const QRect & r);
QSize sizeHint() const;
QLayoutItem * takeAt (int index);
private:
QList<QLayoutItem *> itemList;
};
#endif // STACKLAYOUT_H
とstacklayout。 cppのファイル:
StackLayout::StackLayout()
:QLayout()
{}
StackLayout::StackLayout(QWidget *parent) :
QLayout(parent)
{
}
StackLayout::~StackLayout(){
QLayoutItem *item;
foreach (item, itemList){
delete item;
}
}
void StackLayout::addItem (QLayoutItem * item){
itemList.append(item);
}
int StackLayout::count() const{
return itemList.count();
}
Qt::Orientations StackLayout::expandingDirections() const{
Qt::Orientations result = 0;
QLayoutItem *item;
foreach (item, itemList){
result = result | item->expandingDirections();
}
return result;
}
bool StackLayout::hasHeightForWidth() const{
QLayoutItem *item;
foreach (item, itemList){
if (item->hasHeightForWidth())
return true;
}
return false;
}
int StackLayout::heightForWidth (int w) const{
int result = 0;
QLayoutItem *item;
foreach (item, itemList){
if (item->hasHeightForWidth())
result = qMax(result, item->heightForWidth(w));
}
return result;
}
QLayoutItem * StackLayout::itemAt (int index) const{
if (index<itemList.count())
return itemList[index];
return 0;
}
bool StackLayout::isEmpty() const{
QLayoutItem *item;
foreach (item, itemList){
if (!item->isEmpty())
return false;
}
return true;
}
QSize StackLayout::maximumSize() const{
QSize result=QLayout::maximumSize();
QLayoutItem *item;
foreach (item, itemList){
result = result.boundedTo(item->maximumSize());
}
return result;
}
int StackLayout::minimumHeightForWidth (int w) const{
int result = 0;
QLayoutItem *item;
foreach (item, itemList){
if (item->hasHeightForWidth())
result = qMax(result, item->minimumHeightForWidth(w));
}
return result;
}
QSize StackLayout::minimumSize() const{
QSize result=QLayout::minimumSize();
QLayoutItem *item;
foreach (item, itemList){
result = result.expandedTo(item->minimumSize());
}
return result;
}
void StackLayout::setGeometry (const QRect & r){
QLayoutItem *item;
foreach (item, itemList){
item->setGeometry(r);
}
}
QSize StackLayout::sizeHint() const{
QSize result=QSize(0,0);
QLayoutItem *item;
foreach (item, itemList){
result = result.expandedTo(item->sizeHint());
}
return result;
}
QLayoutItem * StackLayout::takeAt (int index){
if (index < itemList.count())
return itemList.takeAt(index);
return 0;
}
は、あなたはどうしたらそれを挿入するために、あなたはすでにいくつかの素晴らしい透明スクロールバーを持っていると仮定すると:
QWidget* w = new QWidget();
StackLayout* sl = new StackLayout(w);
QListView* lv = new QListView(w);
sl->addWidget(lv);
QHBoxLayout* hbl = new QHBoxLayout();
sl->addItem(hbl);
TransparentScrollBar* tsc = new TransparentScrollBar(w);
hbl->addWidget(tsc,0);
hbl->insertStretch(0,1);
私は、独自のQListViewベースのコントロールを作成し、スクロールバーのカスタム描画を実装することしかできないと思います。明日サンプルコードを書くつもりです。 –
これはQListWidget、btwでなければなりません。これは私のアプリの要求に従って、ライブ "ウィジェット"を行に入れているので、これを使用しています。あなたはQListViewの委任システムでそれを達成することはできません。 – JasonGenX
デリゲートはコンテンツの描画に使用されます。スクロールは内容ではありません。ターゲットはスクロールを隠し、既存のQListWidgetにカスタムスクロールを実装することです。 –