Plotting a semilog chart with Qwt - c++

I would like to plot a semilog chart using Qwt. I have not knowledge about Qwt but I was looking for some examples to guide my code. The problem is that at the moment I don't find someone. Could you help me with a simple code? I want to use a matrix where I can get the x-axis and y-axis values and use them to create the plot. Thank you!

Try this:
QwtPlot *myPlot = new QwtPlot;
QwtPlotCurve *curve1 = new QwtPlotCurve;
 
QwtPointSeriesData* myData = new QwtPointSeriesData;
 
QVector<QPointF>* samples = new QVector<QPointF>;
samples->push_back(QPointF(1.0,1.0));
samples->push_back(QPointF(2.0,2.0));
samples->push_back(QPointF(3.0,3.0));
samples->push_back(QPointF(4.0,5.0));
myData->setSamples(*samples);
curve1->setData(myData);
 
curve1->attach(myPlot);
I used here QVector but qwtplotcurve support double arrays and other things, but I like work with containers. You can choose the best for you. QPoint contains x and y values.
Qwt also offer logarithmic scale engine: http://qwt.sourceforge.net/class_qwt_log_scale_engine.html
I should to say that maybe something wrong with your Qwt, but next code works perfectly on my computer:
#include "mainwindow.h"
#include <QApplication>
#include <qwt_plot.h>
#include <qwt_plot_curve.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QwtPlot *myPlot = new QwtPlot;
QwtPlotCurve *curve1 = new QwtPlotCurve;
QwtPointSeriesData* myData = new QwtPointSeriesData;
QVector<QPointF>* samples = new QVector<QPointF>;
samples->push_back(QPointF(1.0,1.0));
samples->push_back(QPointF(2.0,2.0));
samples->push_back(QPointF(3.0,3.0));
samples->push_back(QPointF(4.0,5.0));
myData->setSamples(*samples);
curve1->setData(myData);
curve1->attach(myPlot);
myPlot->show();
// MainWindow w;
// w.show();
return a.exec();
}

Related

How to make only one point label visible for QLineSeries/QXYSeries

I am using the qtcharts module of qt.
I am using c++ but it does not matter if the solution comes for another language (I will translate it afterwards).
Problem: I plot a bunch of QLineSeries in a QChart and I want to display the point labels only when hovering them.
I planned to use the signal QXYSeries::hovered() to detect when the mouse moves over a point (the same when the mouse moves away the point).
I know that there exists a member function QXYSeries::setPointLabelsVisible() but it makes visible all the points of the series.
I want to be able to display only one point at a time because the series are relatively large and displaying all the labels would degrade the readability.
Question: Is it possible to display only one point label for a QLineSeries ? If yes, how ?
I could not find such a feature anywhere in the Qt documentation.
Here is a baseline code sample to start with (for convenience):
Declaration:
#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
};
Definition:
#include <QApplication>
#include <QLineSeries>
#include <QDateTimeAxis>
#include <QValueAxis>
#include <QChartView>
#include <QDateTime>
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
MainWindow w;
w.show();
return app.exec();
}
MainWindow::MainWindow()
{
setWindowTitle("QtCharts baseline");
resize(800, 500);
QtCharts::QChart * chart = new QtCharts::QChart;
chart->setTitle("Baseline sample");
chart->legend()->setAlignment(Qt::AlignRight);
QtCharts::QDateTimeAxis * time_axis = new QtCharts::QDateTimeAxis;
time_axis->setFormat("hh:mm:ss");
time_axis->setTitleText("Time");
time_axis->setTickCount(5);
QtCharts::QValueAxis * value_axis = new QtCharts::QValueAxis;
value_axis->setTitleText("Value (unit)");
value_axis->setTickCount(6);
chart->addAxis(time_axis, Qt::AlignBottom);
chart->addAxis(value_axis, Qt::AlignLeft);
QtCharts::QLineSeries * ls = new QtCharts::QLineSeries;
ls->setName("Test series");
ls->setPointsVisible(true);
//ls->setPointLabelsVisible(true);
QDateTime dt = QDateTime::currentDateTime();
ls->append(dt.toMSecsSinceEpoch(), -10);
ls->append(dt.addSecs(1).toMSecsSinceEpoch(), 8);
ls->append(dt.addSecs(2).toMSecsSinceEpoch(), 27);
ls->append(dt.addSecs(3).toMSecsSinceEpoch(), 12);
ls->append(dt.addSecs(4).toMSecsSinceEpoch(), 42);
chart->addSeries(ls);
ls->attachAxis(time_axis);
ls->attachAxis(value_axis);
QtCharts::QChartView * view = new QtCharts::QChartView;
view->setChart(chart);
this->setCentralWidget(view);
}
One technique you could try is making a "shadow" copy of the line series with just the one or few points you need, sitting on top of the actual data line. Draw with a transparent pen so the line doesn't show up but set the labels to be visible. You can add/remove/change points to the shadow copy of the line series, and only the labels you want drawn can be added to the series. The link shows one
example of the technique.

QLineSeries does not show up when working with numbers < 1e-14

When graphing a line series within a small range using QtChart library (for example, between 0 and 1e-15), the line series seemingly does not get rendered. Using larger numbers with the same exact code works perfectly.
I've tried boiling down my code to be as simple as possible, to find any mistakes I was making, but I cannot find any. I suspect this may be a bug in Qt, but I'm posting here in case I missed something before I file a bug report.
I've also failed to find any information online about people experiencing similar bugs, but that may just be an indication that my google-fu is weak.
I originally encountered this bug using PyQt5, but have recreated it in C++ to ensure it was not a PyQt5 specific bug.
#include <QtWidgets/QApplication>
#include <QtWidgets/QMainWindow>
#include <QtCharts/QChartView>
#include <QtCharts/QLineSeries>
#include <QtCharts/QLegend>
#include <QtCharts/QValueAxis>
QT_CHARTS_USE_NAMESPACE
#define FACTOR 1e-13
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QLineSeries *lineseries = new QLineSeries();
lineseries->setName("series");
lineseries->setUseOpenGL(true);
for (double i = 0.0; i < 10.0; i += 1.0)
lineseries->append(QPointF(i*FACTOR, i * FACTOR));
QChart *chart = new QChart();
chart->addSeries(lineseries);
chart->setTitle("Line example");
QValueAxis *axisX = new QValueAxis();
chart->setAxisX(axisX, lineseries);
QValueAxis *axisY = new QValueAxis();
chart->setAxisY(axisY, lineseries);
axisY->setRange(0.0, 9.0*FACTOR);
axisX->setLabelFormat("%.3E");
axisY->setLabelFormat("%.3E");
chart->legend()->setVisible(true);
chart->legend()->setAlignment(Qt::AlignBottom);
QChartView *chartView = new QChartView(chart);
chartView->setRenderHint(QPainter::Antialiasing);
QMainWindow window;
window.setCentralWidget(chartView);
window.resize(840, 900);
window.show();
return a.exec();
}
Running the code attached, I would expect to observe a linear line series rendered in the plot, but I see nothing rendered.
Modifying the FACTOR constant to something >= 1e-12 will make the line series display properly.

How to make bullet points bigger in password mode for QLineEdit?

I have a QLineEdit to which I set the echoMode to QLineEdit::Password like this:
myLineEdit->setEchoMode(QLineEdit::Password);
The bullets are shown, but they are too small for the purpose of my application:
I need to make them bigger like this:
I have tried to increase the font size using a stylesheet like that:
myLineEdit->setStyleSheet("QLineEdit { font-size: 20px; }");
This indeed makes the bullets bigger, but the text gets bigger as well.
How to increase the size of bullet points preserving the size of the text?
You can set a unicode character that shows a larger circle through lineedit-password-character:
#include <QApplication>
#include <QFormLayout>
#include <QLineEdit>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
auto lay = new QFormLayout(&w);
QLineEdit *normal_le = new QLineEdit;
normal_le->setEchoMode(QLineEdit::Password);
normal_le->setText("Pass");
lay->addRow("Normal: ", normal_le);
for(int i: {9210, 9679, 9899, 11044}){
QLineEdit *le = new QLineEdit;
le->setEchoMode(QLineEdit::Password);
le->setText("Pass");
le->setStyleSheet(QString("QLineEdit[echoMode=\"2\"]{lineedit-password-character: %1}").arg(i));
lay->addRow(QString::number(i), le);
}
w.show();
return a.exec();
}

QT C++ : Moving several labels at the same time

I have been searching about Threads in QT and ways to process multiple events simultaneously according to their docs, only the main GUI thread can manage GUI related events. So my question is: Is it possible to move multiple labels or objects at the same time during execution? Im trying to create sort of a simulation proyect for school.
What I have right now is: it creates a label everytime I run the function so I need that label to move to a certain spot. Problem is since I need the function executed several times, when it executes again, the previous label stops and moves the new one. After it has completed it goes back to the previous.
Any help is appreciated thanks.
New to asking here and QT in general.
Edit:
Here is what I have of my function:
QLabel *cliente = new QLabel(this);
QPixmap pix("image.jpg");
cliente->setGeometry(10,50,128,128);
cliente->setPixmap(pix);
cliente->show();
int speed = 100;
while (cliente->x()<300){
QTime dieTime = QTime::currentTime().addMSecs(speed);
while (QTime::currentTime() < dieTime){
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
cliente->move(cliente->x()+10,cliente->y());
}
To handle the movement of widgets it is most advisable to use the QPropertyAnimation class, but if you want to handle parallel group animations it is opportune to use QParallelAnimationGroup as shown in the following example:
#include <QApplication>
#include <QLabel>
#include <QParallelAnimationGroup>
#include <QPropertyAnimation>
#include <QWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.resize(500, 550);
QParallelAnimationGroup group;
for(int i = 0; i < 10; i++){
QLabel *label = new QLabel(QString("label %1").arg(i), &w);
QPropertyAnimation *animation = new QPropertyAnimation(label, "pos");
animation->setDuration(1000);
animation->setStartValue(QPoint(50*i, 0));
animation->setEndValue(QPoint(50*i, 50*(i+1)));
group.addAnimation(animation);
}
group.start();
w.show();
return a.exec();
}
Output:

append images in Qlabel (Qt)

I am working on a video processing project. For debugging I need to append ROI of some frames in to QLabel of specified width. I need to append the subframes to the label....Got any ideas for doing that??
You Can Use QLayout(horizintal, Vertical e t.c) and QLabel. Try to dynamically Create QLabels as needed, and the add to the Layout. with this, U can add as Much pictures as you want... Hope it helps.
#include <QtGui/QApplication>
#include <QLabel>
#include <QImage>
#include <QLayout>
#include <QMainWindow>
#include <QStringList>
#include <QDebug>
#include <QScrollArea>
//This assumes that the pictures are in the application's Current working directory
//Four pictures used with names 1.png,2.png,3.png and 4.png respectively
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
QWidget *central = new QWidget(&w);
w.setCentralWidget(central);
QLayout *test_layout = new QVBoxLayout(central);
QStringList file_names;
file_names <<"1"<<"2"<<"3"<<"4";
foreach(QString pics, file_names){
QLabel* imagethings = new QLabel();
QImage image(QString("%1.png").arg(pics));//QImage's Constructor takes a file path
imagethings->setPixmap(QPixmap::fromImage(image));
test_layout->addWidget(imagethings);//append the new image
}
// remove Space as a result of widget Margin(see link for Box Model below)
central->setStyleSheet("QLabel{border:0px; margin:0px; padding:0px;}");
central->layout()->setContentsMargins(0,0,0,0);//remove Spac as a result of Layout Margins
//Please try to take advantage of Qt's Detailed Documentatio that Comes with the SDK
w.show();
return a.exec();
}
http://doc.qt.digia.com/qt/stylesheet-customizing.html -Box Model
http://doc.qt.digia.com/qt/stylesheet-reference.html -Stylesheet Reference
You can Check through the Links for the Stylesheet to discern better