[Solved] Sliding Bar Graph
-
Hello All,
I am in the process of developing an user interface,using Qt, for an embedded system. I have to admit I am very new to Qt and C++ but have been reading through some books.
I would really appreciate if you can guide me through for the following.
- I need to develop a sliding bar graph, that changes (fill color length) dynamically according to the pressure(of fluid in tubings) at that given time.
- Our core application is written in C. We are planning to read various parameters in the C application. Is it possible to get the data from the C application? I went through some a site(cant remember)that we can use QProcess to start a C program that can read data(I might be very wrong here).
I tried searching for the above questions in Internet, but I could not find something.
Thanks for your help
Bsbala -
Hi and welcome!
If you want to keep your core application as a stand-alone process then you need some kind of inter-process communication. Some options are:
- QProcess and use stdin/stdout/stderr/intermediate files etc
- QLocalSocket
- QTcpSocket/QUdpSocket
- dbus
- Shared memory
Or if you would like the GUI to do the actual data acquisition too, then you could refactor your existing application into a shared library that your GUI can link against. It is not difficult to provide GUI and non-GUI versions of an application using Qt in case you still need a headless version.
As for how to draw such an indicator you again have a few options:
- Use an existing widget such as QProgressBar or QSlider
- Use a 3rd party widget such as those from the Qwt project
- Write your own custom widget using QWidget as a base class (using QPainter)
- Write your own custom widget using QGraphicsView framework (canvas-based API)
- Write your own custom widget using QML (declarative framework)
How many such indicators do you need to display at once?
If you need fluid animations and custom appearance (ie maybe with artistic assets from some graphical package) then QML (or QGraphicsView) are probably the way to go.
Hope this helps and good luck with your project!
-
ZapB,
Thank you so much for your reply. I will tryout your suggestions.
With respect to the indicators, We need around 6 of them in the form of sliding graphs. Three of them in the form of normal number displays.I really appreciate your guidance.It would be very helpful in completing this project. I will again post when I am done trying your suggestions.
Best regards,
Bsbala -
Take a look at this "simple progress bar":http://developer.qt.nokia.com/wiki/Simple_QML_Progress_Bar QML item that I knocked together. It should get you going in the right direction.
Of course you may well want to improve the visual appearance using soem custom images for the border and the fill. You could also apply a ColorAnimation to vary the colour of the filled area according to value.
Give us a shout if you want any help on hooking the QML up to the C++ backend.
-
Thanks ZapB.
I had a look into the simple progress bar QML. I will go ahead and see if I can add a different property to it.
I have another question:
I need to interface qt with the back end C application to obtain real time data using any of the process that you suggested(QProcess etc.,) above.
If I do it, is it possible to integrate Qt with the QML user interface and manipulate the properties of the objects(sliding bar graph) on the QML user interface?Thanks for your assistance.
Apologies if I sound very naive.
Balaji
-
Yes this is possible. Some tags to search for on QtDevNet are things like "qml c++ integration".
The basic principal is that you create a C++ class that inherits QObject and in this class you declare some properties using Q_DECLARE_PROPERTY macro. These properties represent the quantities that you wish to display in your QML gui. You then expose your C++ object(s) to the QDeclarativeConext object using the setContextProperty() function.
In you QML gui you can then bind properties of your QML items to the properties of your C++ object(s).
It is up to you how to factor your C++ object(s) and their properties to map onto your data.
This kind of design leads to a nice separation of concerns. You will have a component that retrieves the data from your existing C application somehow and populates the properties of your C++ QObject subclasses. Then you have your GUI in QML which is only dependent upon the names and types of object and properties exposed to it form the C++ side. So you can very easily swap out the GUI for a new one without touching the backend code if needed.
-
Hi,
I tried your progress bar graph illustration it was working fine, when I used it with a single value change from the C++ program.
I am trying to change the graph value with the values from the external "C" program using Qprocess. I am not sure on how to proceed with the program structure. Can you please suggest me. Should the QProcess be a part of some class along with the QML?.
Thanks for your assistance.
Balaji
-
ZapB,
I was able to connect the QML and was able to connect to the output of the C program(the program just outputs from 1 to 100) using QProcess. However the value from the standard output seems to be a stream and the toInt function does not recognize it and returns a value of '0' and the Graph displays with no fill.
Thanks a lot for providing your valuable assistance.
BsBalaThis is the coding for the Qprocess.
@#include <QApplication>
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QDeclarativeProperty>
#include <QGraphicsObject>
#include <QDebug>
#include<QObject>
#include<QProcess>#include "processconnector.h"
#include "slidinggraph.h"ProcessConnector::ProcessConnector(QObject *parent){
process = new QProcess(this);
process->setReadChannel(QProcess::StandardOutput);
connect(process, SIGNAL(readyReadStandardOutput()),this, SLOT(disp()));
process->start("./op");}
void ProcessConnector::disp()
{
while( 1 ){
QString t = process->readLine();
if( t.isEmpty() ) break;
qDebug() << "got output" << t.toInt();
emit valueChanged(t.toInt());}
}
@This is the coding for the QML object.
@#include <QApplication>
#include <QDeclarativeView>
#include <QDeclarativeContext>
#include <QDeclarativeProperty>
#include <QGraphicsObject>
#include <QDebug>
#include<QObject>
#include<QProcess>
#include<slidinggraph.h>SlidingGraph::SlidingGraph(QObject *parent){
view.setSource(QUrl::fromLocalFile("qml/QMLconnector/main.qml"));
QObject object = view.rootObject();
progressbar = object->findChild<QObject>("bar");
view.show();
}void SlidingGraph::setvalue(int value){
if(progressbar)
progressbar->setProperty("value",value);}
@This is the main.cpp
@#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include "processconnector.h"
#include "slidinggraph.h"
#include <QObject>int main(int argc, char *argv[])
{
QApplication app(argc, argv);ProcessConnector *Pc = new ProcessConnector(); SlidingGraph *sl = new SlidingGraph(); QObject::connect(Pc,SIGNAL(valueChanged(int)),sl,SLOT(setvalue(int))); sl->view.show(); return app.exec();
}
@ -
Hi ZapB,
Nice to hear from you. Actually I had my friend code the C part which had some mistakes. He corrected it . I had good sliding graph. Thanks for your help.I got a good idea for working with QML. I have some other questions about QML multiple screens and how to make underlying Qt C++ layer to handle it. I will post it in a new thread. Please help me out if you find some time.
I appreciate all your help, guidance and time you have taken to reply my questions.
Balaji