I'm using QSlider object in my Qt application and I want to get the position of the slider bar upon moving it. I tried using pos() function, but it always returns QPoint() with the same values of x and y (i suppose it returns position of top left corner of slider):
ui->horizontalSlider->pos();
Then I tried dividing the slider width by 100 and adding that value multiplicated by slider value() to most-left position:
SliderStep = ui->horizontalSlider->width()/100;
(ui->horizontalSlider->value()) * SliderStep + ui->horisontalSlider->geometry().x();
It kind of works for me, but values are not very accurate since SliderStep has to be double and coordinates are integer values. I always noticed that I can get slider values by either using value() or sliderPosition() functions since they always return the same value for me:
qDebug()<<ui->horizontalSlider->sliderPosition();
qDebug()<<ui->horizontalSlider->value();
So my question is, is there a more convinient or "right" way to get coordinates of a slider bar? What's the difference between those two functions? Any help is appreciated.
Related
i have an application in qt that loads an image. The user can set a cross by moving the slider with setPixel(). If he decrements the slider, the cross should become smaller and the original pixel should be displayed.
But unfortunately nothing happens when I decrement the slider. The cross keeps its maximum size.
The function, that sets the Pixel
void ImageViewer::applyExampleAlgorithm(int kreuzBreite)
{
if(image!=NULL)
{
for(int i=0;i<((kreuzBreite*std::min(image->width(), image->height())/ 100) / 2);i++)
{
image->setPixelColor(image->width()/2+i,image->height()/2,QColor(255,0,0,0));
image->setPixelColor(image->width()/2-i,image->height()/2,QColor(255,0,0,0));
image->setPixelColor(image->width()/2,image->height()/2+i,QColor(255,0,0,0));
image->setPixelColor(image->width()/2,image->height()/2-i,QColor(255,0,0,0));
}
}
updateImageDisplay();
renewLogging();
}
My Slider
QSlider *slider1 = new QSlider(Qt::Horizontal,0);
slider1->setRange(0,100);
connect(slider1, SIGNAL(valueChanged(int)),this, SLOT(applyExampleAlgorithm(int)));
As you can see, the value changes, but my cross does not.
I think I have to save the original pixel and rewrite it, as soon as the red cross disappears at this point. But I dont really know how.
When the slider value decreases, your function only "draw" a smaller red cross in the bigger one that was drawn before. You can store the original image in a different variable. Then, before drawing the red cross, restore to the original image.
I've defined my vtkLegendScaleActor like this:
vtkSmartPointer<vtkLegendScaleActor> legendScaleActor = vtkSmartPointer<vtkLegendScaleActor>::New();
legendScaleActor->GetLegendLabelProperty()->SetColor(0,0,0);
legendScaleActor->GetLegendTitleProperty()->SetColor(0,0,0);
legendScaleActor->SetBottomAxisVisibility(0);
legendScaleActor->SetTopAxisVisibility(0);
legendScaleActor->SetRightAxisVisibility(0);
legendScaleActor->SetLeftAxisVisibility(0);
legendScaleActor->GetLegendLabelProperty()->SetFontSize(legendScaleActor->GetLegendLabelProperty()->GetFontSize() * 2);
legendScaleActor->GetLegendTitleProperty()->SetFontSize(legendScaleActor->GetLegendTitleProperty()->GetFontSize() * 2);
I wanted to increase the font size in both label and title, and hide all the axis.
The result is:
Where I can see the geometry with the scale rule, but it is cropped by the limits of the window.
I would like to move up the legend, but I could find the right attribute of the given class. Any idea about how to do it?
EDIT
I've continued working on this issue and what I've done is to add a negative offset to the label and the title of the vtkLegendScaleActor object, with:
legendScaleActor->GetLegendTitleProperty()->SetLineOffset(-25);
legendScaleActor->GetLegendLabelProperty()->SetLineOffset(-25);
Having as a result:
Nevertheless, I cannot move the ruler, neither the whole set together... that's why I imagine that there should be a better solution.
Subclass the vtkLegendScaleActor. Then reimplement the BuildRepresentation method and modify the Coordinates of the LabelActors. With this you have full control of the representation, since all Actors and Mappers are protected and therefore modifieable.
I'm trying to program my own progressbar and this I already got working. Each time the percent value changes the bar changes too, so that the bar displays the right progress.
Now my problem is, that the bar always (of course) jumps to the next state and there is no smooth transition between it. Now my question is, how can I make a smooth transition between the stages?
Informations:
I know the fpscount of the game and the position + scale of the bar. And I'm programming in java (I think this information is unnecessary :P)
A general answer, not language specific.
Instead of directly setting the width, you could increase each frame the width until its the desired width/percentage.
Let's assume you have the function bar.setWidth(val) to set the width of your progress bar.
Let this be your update loop (ran at 60FPS):
update {
...
...
double percentageLoaded; // this is your parameter probably
static const int incrementStep = 1; // increase this for faster animation
// Get the width of the bar for the current percentage
int desiredWidth = percentageLoaded * bar.totalWidth;
if(bar.currentWidth < desiredWidth) {
bar.currentWidth += incrementStep;
}
}
There are still a few things you have to check if your incrementStep is larger than 1. (eg: don't set the bar width larger than 100%)
Here is a small drawing, maybe it helps you understand better. In this example the increment step is 1px, the bar width is 4px and the loading was set to be 50% complete, this means that your bar should be 2px in width.
I have drawn a box. The first animation makes the box move horizontally and the second one moves the box vertically. But when the second animation is executed the box first comes back to its original position and then animates vertically. What I want is that the box shouldn't come back to its original position and where the first animation ends, the second animation must execute exactly from that position. How can I achieve this? What am I doing wrong?
JS Fiddle Code
window.onload = function (){
var paper = Raphael(0,0,800,400);
var hi = paper.rect(10,10,100,30);
var move1 = Raphael.animation({
transform:'t100,0'
},1000);
var move2 = Raphael.animation({
transform:'t0,100'
},1000);
hi.animate(move1);
hi.animate(move2.delay(1000));
}
Hey here's the updated working fiddle
The reason being as you may know small t transforms relative to the current position of the rectangle. By current position it means the x and y attributes of the element, the rectangle in our case.
But the first line in Element.transform says
translation doesn’t change x or y of the rectangle
Which means after you perform 't100,0' the x & y attributes of the rectangle is still the initial 10,10 Hence the second animation is executed with respect to 10, 10
Finally, for the result you are expecting, you need to be able to change x & y attributes which can be done as shown in the fiddle....Hope this helps !
I have created my own class by extending QGraphicsItem and I want to make it so that when someone does a wheel even while over this item, it scales.
This way, i can have multiple items in a scene, and scale each of them in and out as I please.
The problem is, I want the item to scale under the mouse cursor, much like google maps does. That is, a move forward will keep panning the image and scaling it, so taht the area in the vicinity around my mouse pointer is always in view.
void ImagePixmapItem::wheelEvent ( QGraphicsSceneWheelEvent * event ){
update();
qreal factor = 1.2;
if (event->delta() < 0)
factor = 1.0 / factor;
scale(factor, factor);
scaleFactor *=factor;
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height());
}
This is the code I am using to do the scale. The problem is, it always seems to be scaling from the top left corner. Well, this is undesirable, beacuse if I scale in or out too much, eventually my area of interest around the mouse pointer has moved off the screen, and I have to either scroll manually or pan to the location, zoom, pan, etc, until i get to the desired level.
I tried to use the QGraphicsItem::setTransformOriginPoint, but no matter what values I put in there, it still seems to scale and such from the top left.
What can I add to that code I posted to get the desired effect?
I have achieved similar functionality in my Image-Manipulation application (scaling the view and having the area under my mouse stay in place and visible) but I scale the whole graphics-view not a specific item, so I don't know if this code can solve your problem.
Anyway, this is what I do in the constructor of my subclassed QGraphicsView (after I set the scene):
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
I also use the above functions, after each call to:
MyGraphicsView->setTransform(transform);
I'm not sure if this can help you, but I hope so.