How to plot with QwtPlot from Qt slot? - c++

Good time of day! I have a question you'll maybe find silly and obvious, but i've already broke my head trying to solve this.
I want to plot some curve by pressing a QPushButton. I wrote the slot and connected it to the corresponding signal of this button. But when I click on it, nothing happens on the plot, although this function executes, and it can be viewed on the debugger and qDebug() output.
On the other hand, if you call this function directly, and not as a slot, it works perfectly. The only difference is the calling method: as a slot in first case and as a method in the second case.
Some code examples:
//Slot
void MainWindow::buttonClick()
{
qDebug() << "Enter";
XRDDataReader *xrdr = new XRDDataReader();
xrdr->fromFile("/home/hippi/Документы/Sources/Qt/49-3.xy");
ui->plot->plotXRD(xrdr->xValues(), xrdr->yValues());
qDebug() << "Quit";
}
void Plotter::plotXRD(QVector<double> x, QVector<double> y)
{
QwtPlotCurve *curve = new QwtPlotCurve();
curve->setRenderHint
( QwtPlotItem::RenderAntialiased, true );
curve->setPen(Qt::black, 2);
curve->setSamples(x,y);
curve->attach(mainPlot);
}

As long as autoreplotting is not enabled, you have to call replot to make changes happen.

Related

Qt5: How to solve this trouble. Custom QWidget with custom paintEvent() vs. QWidget move() function

first post here, I also need it to help others.
I'm just new at QT/c++, but with years of hobby making programming things, I'm progressing relatively fast.
I'm trying to learn it by making a game, so on, I made, besides other things, a custom sprite class that inherits from QWidget.
I reimplemented, as a common practice, the paintEvent function, using some tricks, qpixmap/qpainter, json files, spritesheets, codehelpers made by my self, to succefully play an animation with stances like idle/walking/attacking.
All went perfect until I tried to move it while walking by the function move(int x, int y) from QWidget.
The problem, I think, is that every time I call "move" function it updates/refresh/repaint the QWidget by calling paintEvent function again, chopping my animation, generating several issues, etc. etc.
I can't to figure out how to move it without repainting or waiting the animation to finish, or what I'm missing. It seems there are no other ways to move a QWidget.
I belive the problem is in another event function that's being called by a emitted signal, probably moveEvent, but I reimplemented it keeping it empty and the result was the same.
Do you have any idea? Should I remake it all in another way to skip this trouble? Or is it as simple as I can't see the coin opposite to me?
Ask for code if needed.
Thank you so much, Luna.
EDIT 1:
customsprite::customsprite(QWidget *parent, QString spriteName) : QWidget(parent)
{
// qpm is a QPixmap
qpm_idle.load(":/Assets/sprites/" + spriteName + ".png");
qpm_walk.load(":/Assets/sprites/" + spriteName + "_walk.png");
...
// here goes a custom class to load json files for each sprite sheet
// the json contains x,y,h,w info to draw the animation
...
//some int,bools,qstrings
...
// fps is QTimer
fps.setInterval(33);
connect(&fps,SIGNAL(timeout()),this,SLOT(update()));
fps.start();
}
//the paintEvent:
void customsprite::paintEvent(QPaintEvent *){
//
QPainter qp(this);
QRect targetR(xMove,0,spriteW,spriteH);
QRect sourceR(jhV[status].getFrameX(jhV[status].namesV[spriteFg]),0,spriteW*sizeDivisor,spriteH*sizeDivisor);
// things abouts consulting jsonhelper info
switch (status){ // status is to know if should draw idle or walk animation
case 0:
qp.drawPixmap(targetR,qpm_idle,sourceR);
break;
case 1:
xMove = xMove + 1;
targetR = QRect(xMove,0,spriteW,spriteH);
qp.drawPixmap(targetR,qpm_walk,sourceR);
break;
default:
break;
}
// all this works fine
if(!reversingAnimation && shouldAnimate){ // simple bool options
spriteFg++; // an int counter refering to which frame should be drawed
if(spriteFg == jhV[status].getSSSize()){ // this consults the json files by a custom jsonhelper, it works fine
if(reversible){
reversingAnimation = true;
spriteFg = jhV[status].getSSSize() - 1;
}else if(!reversible){
spriteFg = 0;
emitSignals();
if(animateOnce == true){
shouldAnimate = false;
}
}
}
}
//here goes a similar the above code to to handle the animation playing in reverse, nothing important
}
Then in my generic QMainWindow I add an instance of my customsprite class, set its parent as QMainWindow, it appears, play the animation.
The problem is when I try to use:
//cs is customsprite
cs->move(cs->x()+1,cs->Y());
It moves, but interrumping the animation several times.
I have tried also putting it with a "isWalking" bool filter inside the paintEvent, but it's the same.
EDIT 2:
The "xMove" thing there, is a trick used to succefully and smoothly move the animation, but it need to increase the width of the QWidget to being seen.
Not a good solution.

selected SIGNAL from QwtPlotPicker seems to be sending 3 times

I have a QwtPlot and I need to select a point by clicking on it.
I'm using the QwtPickerClickPointMachine and the QwtPlotPicker classes to do so:
QwtPickerClickPointMachine picker_m = new QwtPickerClickPointMachine();
QwtPlotPicker d_picker = new QwtPlotPicker(QwtPlot::xBottom, QwtPlot::yLeft,
QwtPlotPicker::CrossRubberBand, QwtPicker::AlwaysOn,
dataPlot->canvas()); // dataPlot == QwtPlot
d_picker->setStateMachine(picker_m);
connect(d_picker, SIGNAL(selected(QPointF)), this, SLOT(test(QPointF)));
On my test function I am just printing an output:
void MyClass::test(QPointF point)
{
qDebug() << "test";
}
But the problem is that when I click on the QwtPlot the output is:
test
test
test
It seems to be calling three times. I don't have any idea why this is happening. Can someone give me an explanation please?

Qt c++ Increasing integer with pushButton to label

I'm trying to make a simple "Cookie Clicker" game and I'm having trouble with this. When I press the button I want the label to print out "You have mined (VALUE) FSCoins" but the label won't update for some reason. Console shows no errors :(
Here's my code:
mainwindow.cpp
void MainWindow::on_pushButton_clicked(int num, int numplus)
{
num = numplus + 1;
QString qstr = QString::number(numplus);
ui->label->setText("You have mined " + qstr + " FSCoins");
}
Any help would be appreciated, I've only started working with Qt yesterday and I'm "Sort of" getting the hang of it.
num = numplus + 1;
What is the point of this line? num is a local variable that is never used. Did you mean to pass it by reference?
You need to connect a SIGNAL to a SLOT, but that function you wrote there does not seem like a SLOT. Somewhere in your code there shall be something like this in your header file:
class ...
{
// ...
private slots:
void onPushButtonClicked();
};
and in your source file:
// For example in the constructor.
connect( ui->PushButton, SIGNAL( clicked() ), this, SLOT( onPushButtonClicked() ) );
// The implementation of your SLOT.
Class::onPushButtonClicked()
{
// Your implementation.
updateLabel( /* Your arguments */ );
}
The SLOT function cannot have more arguments than the SIGNAL, so in this case your SLOT cannot have any.
And something else. I prefer this version of creating a QString:
QString( "You have mined %1 coins" ).arg( value );
I think it's more readable.
So the point is that that you need store that integers somewhere. Maybe in your class as a member variable.

(Qt C++) Send int value from dialog to MainWindow?

I am quite new to C++ and Qt. I've gotten pretty far on my current project, but I've been putting off this one part. I have a pushbutton that opens a new dialog like this:
void MainWindow::on_fillAll_clicked()
{
int yo;
BlockSelect bSelect;
bSelect.setModal(true);
bSelect.exec();
if( bSelect.exec() == QDialog::Accepted )
{
//Get stuff here?
//I want to fill yo with the spinbox value
yo = bSelect.stuff();
return;
}
qDebug() << yo;
}
This works fine. In the dialog I have a spin box. I want to send that value inputted to the spin box to my main window when the user clicks OK.
I have been trying to get "int yo;" to have that value from the spinbox but everything I try just gets an error.
I added this to my BlockSelect public class:
int stuff();
And I made this function in my blockselect.cpp:
int BlockSelect::stuff()
{
qDebug() << "The function was called";
return ui->yolo->value();
}
But qDebug never shows anything???
So how can I fill yo from the main window with yolo from the dialog?
Sorry if I didn't explain this well :( I'm still learning.
Thanks for your time :)
First of all, there is no need to call exec() twice, just use it once within the if statement.
To answer your question, you still have the bSelect dialog object (and I'm assuming BlockSelect is a class you define?), so make an accessor function inside it to retrieve the values you want.
if( bSelect.exec() == QDialog::Accepted )
{
//Get stuff here?
//I want to fill yo with the spinbox value
yo = bSelect.stuff();
return;
}
EDIT:
Your BlockSelect class needs to contain an accessor function, this means a function that returns a value.
int stuff() { return ui->yolo->value();}
What I'm doing here is retrieving the spinbox's value (assuming it is named 'yolo') and returning it as a result of calling the 'stuff' function.

mousePressEvent called only from certain areas in scene

I have an application which draws lines based on different data from cars. I want my application to be able to select the lines drawn, and then make the corresponding item selected in a list on the left as well. The problem is that the mousePressEvent is only called when I press the mousebutton in the leftmost quarter of the scene. When it is called the curveSelected() function works as well, but I can't figure out why I can't invoke the mousePressEvent from the other areas on the scene.
First of all I have a mousePressEvent.
void DrawingScene:::mousePressEvent ( QGraphicsSceneMouseEvent * event ){
event->ignore();
bool leftbutton = (event->button() == Qt::LeftButton);
if(leftbutton)
{
qDebug() << "leftbutton";
emit leftButtonPress(event->scenePos());
}
QGraphicsScene::mousePressEvent(event);
}
Later connected:
connect(d_scene, SIGNAL(leftButtonPress(QPointF)), this, SLOT(curveSelected(QPointF)));
leftButtonPress is the signal emitted. Then I have the function which selects the item in the list. This method seems to work just fine. The problem exists without this function as well.
void CurveDrawer::curveSelected(QPointF pos){
QMapIterator<QPair<unitID, QString>, carData*> it(dataMap);
while(it.hasNext()){
it.next();
QPainterPath curPath = it.value()->pathItem->path();
if(curPath.contains(pos)){
for (int i = 0; i < list->count(); ++i) {
QListWidgetItem* curItem = list->item(i);
if(curItem == it.value()->listItem){
qDebug() << "curveSelected";
curItem->setSelected(true);
}
}
}
}
}
Anyone experienced something similar, or may see some obvious mistakes in my code?
EDIT:
How can i achieve that the mousePressEvent is called every time I click inside the scene? This is basically what I want it to do. Now it is only called when I click in certain area.
I tried to implement it with void DrawGraphicsView;;mousePressEvent(QMouseEvent *event) now, and the same problem existed there. The event just got invoked from certain areas in the scene.
The strange thing for me is that when a certain place in the scene is in the left of the viewport it is not possible to invoke the mousepressEvent, but when I scroll the same place to the right in the viewport, then it is suddenly possible to invoke the mousepressEvent. Does this make the problem clearer?