Seite 1 von 1
eigene Scroolbar
Verfasst: 5. Dezember 2004 19:49
von cyc
Hi,
Bei meinem graphischen Plotter-Widget möchte ich eine Scrollbar hinzufügen, die eine Vorschau der gesammten Daten bietet und das den Scrollbarbutton (der den sichtbaren Bereich im Gesammtbereich darstellt) z.B. rot durchsichtig anzeigt.
Das ganze funktioniert auch schon... allerdings nicht als eigenständiges Widget.
Kann ich jetzt einfach mein Scrollbarwidget von QScrollbar ableiten und das paintEvent mit meiner Zeichenroutine überschreiben?
Verfasst: 5. Dezember 2004 20:37
von lepsai
Ich glaube einfacher und irgendwie korrekter wäre es, QStyle teilweise zu reimplementieren. Anleitung dazu findest du im Qt Beispiel "themes".
Verfasst: 5. Dezember 2004 22:16
von cyc
auch wenn die Vorschau auf der Scrollbar dynamisch sein soll?
Verfasst: 5. Dezember 2004 23:30
von lepsai
Willst du denn die zu plottenden Daten auf einer Scrollbar darstellen?!!!!
einen Sinn für Humor hast auf jeden Fall!
Schick mir mal ein Screenshot von dem ,was du jetzt hast, an
lepsai@imagingtools.de...
Aber auch dabei spricht nix gegen QStyle. Nur der Datentransfer muss geregelt werden...
Verfasst: 6. Dezember 2004 21:14
von cyc
Oje, damit hab ich mit meiner vereinfachten Darstellung meines Problems wohl mehr Verwirrung gestifftet als es geholfen hat. In Wirklichkeit sollen auf der Scrollbar nicht der Plot sondern die Dichteverteilung der gemessenen Daten dargestellt werden. Sinnvollerweise soll der Scrollbar Slider nur durchsichtig und einfarbig sein und damit der aktuell sichtbare Bereich der Gesammtdaten ausgewählt werden können.
Der Code im macht nix anderes als
- weissen Hintergrund im sb.rect() zeichnen
- Dichtedaten ebenfalls in sb.rect() rendern
- aktuell sichtbarer Bereich des Plots vom Gesammtbereich
auf Scrollbar umrechnen und dort ein Qt::cyan Rechteck mit XOR zeichnen damit es dann Rot und durchsichtig erscheint
Grüße
Timo
Verfasst: 7. Dezember 2004 08:19
von Christian81
Jetzt ist es klarer

Sowas ähnliches wird bei graphischen diff-Tools (WinMerge, KDiff3,...) gemacht. Allerdings werden selbst bei kdiff3 2 Bars benutzt.
Im Grunde sollte es so gehen wie Du gesagt hast. Allerdings würde ich die Dichteverteilung nicht jedes Mal neu berechnen sondern irgendwo zwischenspeichern. Mit XOr muss man auch nicht rumspielen - ein Alpha-Blending (siehe QImage) sollte da imho reichen.
Verfasst: 7. Dezember 2004 13:51
von cyc
ok mein repaintEvent Überschreibversuch war nicht vom Erfolgt gekrönt.
Kann mir jemand einen Tip geben wie ich das mit Styles mache?
Verfasst: 7. Dezember 2004 14:00
von lepsai
paintEvent() von QScrollBar ruft im Wesentlichen die
style().drawComplexControl(QStyle::CC_ScrollBar, p, this, rect(), colorGroup(),flags, (QStyle::SubControl) controls,(QStyle::SubControl)activeControl );
d.h. du könntest schreiben:
class MyStyle : public QWindowsStyle // oder QSGIStyle oder QCDEStyle
{
MyStyle(..., const MyPlotData & data)
// und denn reimplementieren:
void drawComplexControl(...);
protected:
MyPlotData m_data;
};
qApp->setStyle(new MyStyle);
// und fertig bist du...
Verfasst: 7. Dezember 2004 14:00
von lepsai
paintEvent() von QScrollBar ruft im Wesentlichen die
style().drawComplexControl(QStyle::CC_ScrollBar, p, this, rect(), colorGroup(),flags, (QStyle::SubControl) controls,(QStyle::SubControl)activeControl );
d.h. du könntest schreiben:
class MyStyle : public QWindowsStyle // oder QSGIStyle oder QCDEStyle
{
MyStyle(..., const MyPlotData & data)
// und denn reimplementieren:
void drawComplexControl(...);
protected:
MyPlotData m_data;
};
qApp->setStyle(new MyStyle);
// und fertig bist du...
Verfasst: 7. Dezember 2004 14:31
von cyc
Danke schonmal.
Ändert das alle ScrollBars in der Application?
Das sollte nämlich nicht sein (mein Widget ist nur ein Teil einer grösseren MDI Anwendung).
Verfasst: 7. Dezember 2004 15:18
von lepsai
ja, das würde alle Widgets entsprechend ändern. Das kann man aber in der draw...()-Funktion abfangen, so dass nur der Widget der Klasse X geändert wird.
Verfasst: 8. Dezember 2004 17:48
von cyc
Ok, beim testen der Styles bin ich auf folgendes Problem gestossen:
Meine header Datei sieht folgendermassen aus:
Code: Alles auswählen
#include <qwindowsstyle.h>
#include <qpalette.h>
#include <qpainter.h>
#ifndef QT_NO_STYLE_WINDOWS
class ScrollBarStyle : public QWindowsStyle
{
public:
ScrollBarStyle();
~ScrollBarStyle();
void drawPrimitive( QStyle::PrimitiveElement pe,
QPainter *p,
const QRect &r,
const QColorGroup &cg,
SFlags flags = Style_Default,
const QStyleOption& = QStyleOption::Default ) const;
};
#endif
und meine cpp Datei:
Code: Alles auswählen
#include <ScrollBarStyle.h>
ScrollBarStyle::ScrollBarStyle():QWindowsStyle()
{
}
void ScrollBarStyle::drawPrimitive( PrimitiveElement pe,
QPainter *p,
const QRect &r,
const QColorGroup &cg,
SFlags flags,
const QStyleOption& opt ) const
{
if (pe == PE_ScrollBarSlider)
{
if (flags & Style_Enabled)
{
p->setPen(Qt::red);
p->setBrush(Qt::red);
} else
{
p->setPen(Qt::darkRed);
p->setBrush(Qt::darkRed);
}
p->drawRect(r);
} else
{
QWindowsStyle::drawPrimitive(pe, p, cg, flags, opt);
}
}
führt aber zu folgender Fehlermeldung (qt-free-x11-3.2.1):
Code: Alles auswählen
ScrollBarStyle.C: In member function `virtual void
ScrollBarStyle::drawPrimitive(QStyle::PrimitiveElement, QPainter*, const
QRect&, const QColorGroup&, unsigned int, const QStyleOption&) const':
ScrollBarStyle.C:55: no matching function for call to `QWindowsStyle::
drawPrimitive(QStyle::PrimitiveElement&, QPainter*&, const QColorGroup&,
uint&, const QStyleOption&) const'
/share/opt/qt-x11-free-3.2.1-g++-3.3.1/include/qwindowsstyle.h:69: candidates
are: virtual void QWindowsStyle::drawPrimitive(QStyle::PrimitiveElement,
QPainter*, const QRect&, const QColorGroup&, unsigned int = Style_Default,
const QStyleOption& = QStyleOption::Default) const
Warum? Dachte ich hätte das Qt Beispiel richtig abgetippt.
Verfasst: 8. Dezember 2004 20:10
von Christian81
Hast Du evtl. das QRect vergessen mit zu übergeben?
Code: Alles auswählen
QWindowsStyle::drawPrimitive(pe, p, cg, flags, opt);
-->
QWindowsStyle::drawPrimitive(pe, p, r, cg, flags, opt);
Verfasst: 10. Dezember 2004 16:23
von cyc
Ja klar, danke. Man gebe mir einen Blindenhund.