How to get the position of the first and the last tick mark in a Qslider? - qt

I want to draw a tick mark for a qslider in paintEvent, so I should get the exact position of each tick mark. As you know, the handle of slider takes some space, so the first tick mark does not sit at the left/top position of the slider, there is offset of several pixels. Same thing happens to the last tick mark which indicates the maximum value. I want to know how many pixels of the space? (On win and mac, the handle are not in the same width)

If you have not yet done so, download the Qt source code and copy how they do it. You will want to look in the various Q...Style classes, i.e QMacStyle, QWindowsXPStyle, etc. Some of the key calculations come from:
QStyle::sliderPositionFromValue() method
QStyle::pixelMetric(QStyle::PM_SliderTickmarkOffset, ...)
Look in the various drawComplexControl methods for case CC_Slider:, where slider controls are drawn. In the Qt 4.7 code, this starts on line 2699 in qwindowsxpstyle.cpp, for example.

Related

how to add handles to a corner in fontforge

Corner points in fontforge (seemingly also known as "coins", shown as squares in the UI), can have zero, one, or two handles to control the direction of the outgoing lines. This fact is nicely explained in the manual, but I cannot find any hints on how to control the number of handles.
How do I change the number of Bézier handles of a corner point?
In my specific case I have a straight line between two corners, and I would like to change this line to "bulge outwards" a bit. I tried to add a "curve point" between the two corners, but this gives me a strange curve point with no handles, which seems to be functionally identical to just another corner.
The simplest way to make a line bulge is to grab the line and drag (ensure the surrounding corner points are not selected first). This will immediately turn it from a line into a curve, and create control points. If you want to turn it back into a straight line, select the surrounding corner points then right-click the line and choose "Make Line".
You could equally add a curve point between the corners (CTRL-ALT-click where you want to add) and then merge it back out of existence using CTRL-M. This will leave the line as is, but with control points available.
Note that control points won't display unless you have selected an adjacent corner point or curve point. You can make them always display by selecting View>Show>Control Points (Always).
Very occasionally you may encounter what looks like a line but is actually a curve in which the control points coincide exactly with the corner points. The above methods will work fine in this situation too.

How to get the length of the left/right offsets in a QSlider?

I'm trying to make a subclass of QSlider that allows the user to insert "bookmarks" so they can remember significant locations on the slider. I've run into a problem painting the tabs on the slider - using QStyle.sliderPositionFromValue, I get a value but it is slightly inaccurate. If I'm on the left side of the slider, the tab is painted too far left, and on the right side it is painted too far right. I believe this is because QSlider.width() returns the width of the whole object, including the small offsets at the left and right. So width() might return 630 pixels, when the length of the slider itself is really 615.
This is the code I'm using to get the pixel position and draw a line across the slider.
pos = QStyle.sliderPositionFromValue(self.minimum(),self.maximum(),sliderIndex,self.width())
painter.drawLine(pos,0,pos,self.height())
I've been looking at the QT Source here starting on line 2699 and it seems like I need to be using the PixelMetric class from QStyle. I've tried using:
self.style().pixelMetric(QStyle.PM_SliderSpaceAvailable)
But that returns 0, which is clearly not the value I need.
I'd appreciate any advice.
Edit: As suggested in the comments, I changed the call to:
self.style().pixelMetric(QStyle.PM_SliderSpaceAvailable, QStyleOption(1,QStyleOption.SO_Slider),self)
This however, returns -14, which also doesn't match for the value of the offsets (I tried using self.width()-14 but the offset remains.

qscrollbar (not a qscrollarea) setValue not working

I am working on a qwtPlot and have implemented custom scrollbars to illustrate the position of things on the plot when zooming in (in regards to the whole thing - so basically the percentage).
Now, everything works fine, apart from the moment, when I do any zooming or panning right at the beginning (or simply when I see the whole plot and then I want to zoom in).
This is a slot I am using to refresh the appearance of the scrollbar:
void ScrollHorizontal::refreshAfterChanges() {
setValue(myPlot->getLowerBound(QwtPlot::xBottom));
setPageStep(myPlot->get_X_delta());
setSingleStep(myPlot->get_X_delta()/10);
setMaximum(myPlot->dataFromSources->lastTimeValMicro()-pageStep());
update();
printV("HorizontalScroll::setValue",myPlot->getLowerBound(QwtPlot::xBottom));
printV("value", value());
printV("pageStep", pageStep());
in the constructor I set the maximum to 0 (just in case, but it doesn't change anything)
The last 3 lines print out some values useful for debugging. What I found out thanks to them is that the slot is executed correctly, but the setValue(int) function doesn't work as I would expect it to:
//printed values right after starting the program
HorizontalScroll::setValue=0
value=0
pageStep=7320
//printed values after using the zoomer once
HorizontalScroll::setValue=956.316
value=0
pageStep=2225
Then, when I move the plot a tiny bit, e.g. zoom it 1.1 times, the setValue works properly and value() return the same thing I set. But if I go to the 100% view (the starting point) I get the same problems again.
Just to illustrate it, here are some screenshots:
http://tinypic.com/view.php?pic=2znph7s&s=8#.UvNkDoZhauY
(100% view, right before zooming in)
http://tinypic.com/view.php?pic=ke7nn9&s=8#.UvNkYIZhauY
(badly set qscrollbar)
Ok - problem was caused by the line
setMaximum(myPlot->dataFromSources->lastTimeValMicro()-pageStep());
It was setting the maximum to 0 sometimes. why? I wanted the slider to take up the whole length of the scrollbar so that at the beginning when the plot was shown in 100% view, you couldn't scroll it and I could achieve that by setting the pagestep to my plot's maximum value and the maximum to 0.
But that caused the setValue(int)problem - you can't set a value bigger than the maximum.
So what finally worked for me is:
double valueToSet=myPlot->getLowerBound(QwtPlot::xBottom);
if(valueToSet>maximum())
setMaximum(valueToSet);
setValue(myPlot->getLowerBound(QwtPlot::xBottom));
setPageStep(myPlot->get_X_delta());
setSingleStep(myPlot->get_X_delta()/10);
setMaximum(myPlot->dataFromSources->lastTimeValMicro()-pageStep());
update();

Antialiasing in Qt's QGraphicsScene make overlapping lines darker

When using anti-aliasing rendering in Qt's QGraphicsScene, there is a behavior that makes drawings appear not as expected: overlapping lines become darker. I could not see any description of this behavior in the documentation, and I cannot find a way to disable it.
For example if I want to draw such a polygon:
Because of the number of points, it is impossible not to have overlapping lines - fine. But because anti-aliasing is activated, some borders appear 'thicker' than others.
Is there any way to avoid this and have anti-aliased lines that can overlap and yet at the same time be rendered without getting darker?
I know of course that I can redefine the paint() function and draw manually individual lines that do not overlap, but this is what I want to avoid. I am using Pyside and this would significantly slow down the application, due to the high frequency at which paint() is being called.
EDIT Fixed by defining the object shape using QPainterPath / QGraphicsPathItem instead of QPolygon / QGraphicsPolygonItem. In that case the moveTo function allows to avoid lines that overlap.
Another thing you could try is adding half a pixel to your coordinates (not dimensions). This fixed the anti-aliasing issue for me.
XCoord = int(XValue) + 0.5
YCoord = int(XValue) + 0.5
Also make sure that before that you have integer pixel values.

How to make qt qgraphicsview scale to not affect stipple pattern?

I draw few rectangles inside the QGraphicsView ; I use custom stipple pattern for these by creating a QBrush with my QPixmap. This gets displayed with the default zoom level as expected.
When I call view->scale(), the rectangles show up bigger or smaller as I expected. However Qt has scaled the individual bits of the stipple pattern which is not expected; I expected it to draw the larger or smaller rectangle again with the brush.
Eg.
If I had used a stipple pattern with one pixel dot and pixel space, after zooming in, I want to see a larger rectangle but I want the same stipple pattern with same pixel gaps. Is this achievable somehow? Thanks.
I ran into the same problem while developing an EDA tool companion in Qt.
After some trying, what I did (and seems to work for me) is to create a custom graphics item. On the paint method, I do:
QBrush newBrush = brush_with_pattern;
newBrush.setTransform(QTransform(painter->worldTransform().inverted()));
painter->setBrush(newBrush);
That is to apply the inverse transformation of the item to the brush (so it does not scale).
I think that the setDashOffset is only for the border of the shapes (not the fill).
You may use QPen::setDashOffset:
http://harmattan-dev.nokia.com/docs/library/html/qt4/qpen.html#setDashOffset
You'll need to set the offset based on the scenes zoom/scale level. You can grab a pointer to the scene in your item by calling scene(), don't forget to check for NULL though since it will be NULL when not added to the scene (although you shouldn't in theory get a paint() when not in a scene).
The other option is to use:
http://doc.qt.digia.com/qt/qpainter.html#scale
To undo the views scaling on your painter.
In case anyone is still looking on this, a related question here regarding scaling of standard fill patterns instead of pixmap fill patterns may help. Basically, it may not be possible to modify scaling of standard fill patterns (a few workaround ideas are listed), but, working with alpha values instead gives the desired effect if you are looking for varying colors, especially gray levels - and is much less convoluted.

Resources