Skip navigation.
Home
The QNX Community Portal

View topic - QLinearGradient not working

Page 1 of 1

QLinearGradient not working

PostPosted: Mon Oct 07, 2013 1:05 pm
by Noir
Hi @ all

I tried to add a QLinearGradient in my qt-program, but after porting to QNX there is no gradient..
The color is displayed, but it is just switching from black to blue without changes in between.
So I am wondering: Is a Gradient from qt not possible in QNX? What is the requirement for using a gradient? (like some specific module, or a library?)

EDIT:

I played a bit around and this is the initialisation:

Code: Select all
    gradient = new QLinearGradient(0,scene->sceneRect().top(), 0, scene->sceneRect().bottom());
    gradient->setColorAt(0, QColor(Qt::darkBlue)); 
    gradient->setColorAt(0.3, QColor(Qt::black));
    gradient->setColorAt(0.7, QColor(Qt::black));
    gradient->setColorAt(1, QColor(Qt::darkBlue));
    brushBlue = new QBrush(*gradient);

    gradientRed = new QLinearGradient(0,scene->sceneRect().top(), 0, scene->sceneRect().bottom());
    gradientRed->setColorAt(0, QColor(Qt::darkRed));
    gradientRed->setColorAt(0.3, QColor(Qt::black));
    gradientRed->setColorAt(0.7, QColor(Qt::black));
    gradientRed->setColorAt(1, QColor(Qt::darkRed));
    brushRed = new QBrush(*gradientRed);


I set it on different times in my code with:
Code: Select all
view->setBackgroundBrush(*brushBlue);


Now the interesting this is:
The Brsuh with the blue gradient is not working (clear cut between the colors), but the Red Brush is working.
Any idea why?

And how can I change the resolution for the gradient? Because I can see the lines from the gradient and this doesn´t look so good..

EDIT 2:

after some changes with the color (darkBlue to black, darkRed to black, darkGreen to black) I found some differences in the resolution or "steps" to change the color.
darkBlue -> black: 1 step. either black or blue
darkRed -> black: around 13 steps. you can still see the changes with some cuts
darkGreen -> black: around 40 or 50 steps. you can still see the changes but looks better

What could be the reason for this? It looks like that it is possible for the BeagleBoard and QNX to make a gradient, but why so different for different colors???

I also tried with different colors and not only the "dark"-variants, but blue is still the looser (3 steps) and yellow, green and red have the most steps.

Re: QLinearGradient not working

PostPosted: Mon Oct 07, 2013 4:04 pm
by maschoen
The QNX specific Qt code merely blits data from a Qt buffer to the hardware buffer. There could be a video mode issue, or a Qt problem. What version of Qt are you using? If it is the 4.7 QNX port, I'd be willing to try the code for you on 4.8.2 if you will post it.

Re: QLinearGradient not working

PostPosted: Mon Oct 07, 2013 5:05 pm
by Noir
I use Qt 4.7.1 for QNX.
I cannot post the code, because I make this program for my thesis.
And it is already too much code for posting (But thanks alot for the offer :) )

On my win8-machine I use Qt 4.7.4 with MinGW and it is working. So does this hint to a video mode issue on the QNX machine?
If so I will try to contact Dennis on Foundry27 (he made the demo-OS I use as a basis on my beagleboard)

Re: QLinearGradient not working

PostPosted: Mon Oct 07, 2013 5:27 pm
by maschoen
If you don't want to post the entire code, I would try creating a small program that just shows the problem. If you contact Dennis, he will probably want something like this anyway.

Re: QLinearGradient not working

PostPosted: Mon Oct 07, 2013 5:55 pm
by Noir
True :D
I will try to make one

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 10:19 am
by Noir
EDIT: --- deleted---

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 10:22 am
by Noir
Ok, here is the minimal program with the basic architecture I am using. After building in Momentics and porting to BeagleBoard-xM I get the same problem -> gradient is not working well/correct.

The kommunikation class is for the communication with the rs232 interface which I use to read data from my laptop. This class is running in a seperate thread.
For the communication I send first a value for the switch-loop ("100" in this case) and then the value (for design change "0" and "1" at the moment).
This value is then emitted via a signal to the main-thread and received from the function "setDesign()" in controller.cpp

main.cpp
Code: Select all
#include "controller.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Controller *control = new Controller;
    control->view->show();
    return a.exec();
}


controller.h
Code: Select all
#ifndef CONTROLLER_H
#define CONTROLLER_H

#include <QWidget>
#include <QtGui/QApplication>
#include <QtGui/QGraphicsView>
#include <QThread>
#include <QtCore>
#include "kommunikation.h"

class GraphicsView : public QGraphicsView
{
public:
    GraphicsView(QGraphicsScene *scene) : QGraphicsView(scene)
    {}
protected:
    virtual void resizeEvent(QResizeEvent *event)
    {}
};

//------------------------------------------------------------------
//------------------------------------------------------------------
class Controller  : public QWidget
{
    Q_OBJECT
public:
    explicit Controller(QWidget *parent = 0);
    GraphicsView *view;
    Kommunikation *worker;

public slots:
   void setDesign(int);

private:
    QGraphicsScene *scene;
    QThread *thread;
    int design;
    QLinearGradient *gradient;
    QBrush *brushBlue;
    QLinearGradient *gradientRed;
    QBrush *brushRed;
};
#endif // CONTROLLER_H



controller.cpp
Code: Select all
#include "controller.h"

Controller::Controller(QWidget *parent) :
    QWidget(parent), design(0)
{
    scene = new QGraphicsScene(-400, -300, 800, 600);
    view = new GraphicsView(scene);
    thread = new QThread();
    worker = new Kommunikation();

    view->setRenderHint(QPainter::Antialiasing);
    view->setBackgroundBrush(QBrush(Qt::black));
    view->setFrameStyle(QFrame::NoFrame);
    view->showFullScreen();

    gradient = new QLinearGradient(0,scene->sceneRect().top(), 0, scene->sceneRect().bottom());
    gradient->setColorAt(0, QColor(Qt::darkBlue));
    gradient->setColorAt(0.3, QColor(Qt::black));
    gradient->setColorAt(0.7, QColor(Qt::black));
    gradient->setColorAt(1, QColor(Qt::darkBlue));
    brushBlue = new QBrush(*gradient);

    gradientRed = new QLinearGradient(0,scene->sceneRect().top(), 0, scene->sceneRect().bottom());
    gradientRed->setColorAt(0, QColor(Qt::darkRed));
    gradientRed->setColorAt(0.3, QColor(Qt::black));
    gradientRed->setColorAt(0.7, QColor(Qt::black));
    gradientRed->setColorAt(1, QColor(Qt::darkRed));
    brushRed = new QBrush(*gradientRed);

    setDesign(0);

    worker->moveToThread(thread);

        QObject::connect(thread, SIGNAL(started()), worker, SLOT(process()));
        QObject::connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
        QObject::connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
        QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
        QObject::connect(worker, SIGNAL(setDesign(int)), this, SLOT(setDesign(int)));

    thread->start();
}

void Controller::setDesign(int b)
{
      design = b;
          switch(design)
          {
            case 0:
               view->setBackgroundBrush(*brushBlue);
               break;
            case 1:
               view->setBackgroundBrush(*brushRed);
               break;
          }
           scene->update();
}


kommunikation.h
Code: Select all
#ifndef KOMMUNIKATION_H
#define KOMMUNIKATION_H

#include <QObject>
#include <QDebug>
#include <termios.h>
#include <fcntl.h>
#include <string.h>
#include <process.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/neutrino.h>

class Kommunikation : public QObject
{
    Q_OBJECT
public:

    Kommunikation();
    ~Kommunikation();

public slots:
    int portInit();
    void process();

signals:
    void finished();
    void eror(QString er);
    void setDesign(int);

private:
    int choice;
    int value;
    int count;
    int speed;
    int fd;
    char data[3]; 
    char intArr[4];
    int intData;
    struct termios raw;
};

#endif // KOMMUNIKATION_H



kommunikation.cpp
Code: Select all
#include "kommunikation.h"

Kommunikation::Kommunikation()
{}

Kommunikation::~Kommunikation()
{}

int Kommunikation::portInit()
{
        //---------------------------------------------------
        //---------------------------------------------------
            // Open the port
            if ((fd = open ("/dev/ser1", O_RDWR)) == -1)
            {
                   fprintf(stderr, "Error with open() on /dev/ser1. Make sure exists.\n");
                   perror (NULL);
                   exit(EXIT_FAILURE);
            }

            // Get the attributes
            if (tcgetattr( fd, &raw))
            {
                   close( fd );
                   return -1;
            }

            // Set input baud rate
            speed = B115200;
            cfsetispeed(&raw, speed);//inputspeed
            cfsetospeed(&raw, speed);//outputspeed

            raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON );
       raw.c_oflag &= ~(OPOST);
            raw.c_cflag &= ~(CSIZE|IHFLOW|OHFLOW);
            raw.c_cflag |= CS8 | CREAD | CLOCAL;
            raw.c_cflag &= ~CSTOPB;
            raw.c_cflag &= ~PARENB;

            raw.c_lflag &= ~(ECHO | ICANON | ISIG | ECHOE | ECHOK | ECHONL | IEXTEN);

            raw.c_cc[VMIN] =  1;
            raw.c_cc[VTIME] = 0;

            if ( tcsetattr( fd, TCSADRAIN, &raw ) == -1 )   // CHECK FOR -1 failure here - this is the actual "set" and it must succeed on nothing may have changed
            {
                   fprintf(stderr, "Error with tcsetattr() on /dev/ser1.\n");
                   perror (NULL);
                   exit(EXIT_FAILURE);
            }
            return fd;
}

void Kommunikation::process()
{

    choice = 0;
    value = 0;
    count = 0;
    fd = 0;

     fd = portInit();

    while(1)
    {
        for(int i = 0; i < sizeof(data); i++)
        {data[i] = 0;}

        for(int i = 0; i < sizeof(intArr); i++)
        {intArr[i] = 0;}

        count = read(fd, data, 3);

        if(data[1] == 0){value = ((int)data[2]);}
        if(data[1] == 1){value = ((int)data[2]) + 127;}
        if(data[1] == 2){value = ((int)data[2]) + 254;}
        if(data[1] == 3){value = ((int)data[2]) + 381;}
        if(data[1] == 4){value = ((int)data[2]) + 508;}
        if(data[1] == 5){value = ((int)data[2]) + 635;}
        if(data[1] == 6){value = ((int)data[2]) + 762;}
        if(data[1] == 7){value = ((int)data[2]) + 889;}
        if(data[1] == 8){value = ((int)data[2]) + 1016;}

        switch(value)
        {
        case 100:
           count = read(fd, intArr, 2);
            if(intArr[0] == 0){intData = ((int)intArr[1]);}
            if(intArr[0] == 1){intData = ((int)intArr[1]) + 127;}
           emit setDesign(intData);
           break;
        }
    }
}

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 12:17 pm
by maschoen
Disclaimer, I did not look at the details of your code.

I compiled it on my 6.5 system using Qt 4.8.2. I ran the code in two modes,

1) Natively without Photon running
2) With Photon running using my phqt program

In both cases I saw a blank screen with a gradient that started on the top dark blue, became black in the center and then became dark blue on the bottom again.
I've attached a .jpg with a screen dump.

Assuming that this is what you wanted, there are two possible explainations.
1) There's been a bug fix since 4.7.
2) Our hardware is different, and Qt works properly on mine, but not yours.

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 2:18 pm
by denkelly
Could the "failure" be to lack of color depth? Mitchell's desktop 24bit RGB, beagleXM 16bit RGB?

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 4:49 pm
by maschoen
denkelly wrote:Could the "failure" be to lack of color depth? Mitchell's desktop 24bit RGB, beagleXM 16bit RGB?


Dennis,

You got me curious about this. The original version of my phqt program had 32 bit hard coded. I tried running the program with Photon in a 16 bit mode. This worked, but all it proved was that Photon properly blits a 32 bit image to a 16 bit graphic mode. So I upgraded the rest of the software so I could run the Qt program in 16 bit also. It appears to continue to work. I'm uploading the screen dump. If you look very carefully, you can see that the color changes are a little bit coarser than they were in 32 bit mode.

So if there is a problem with 16 bit, it was fixed by 4.8.2.

Mitchell

Re: QLinearGradient not working

PostPosted: Tue Oct 08, 2013 5:24 pm
by denkelly
>>>the color changes are a little bit coarser than they were in 32 bit mode.
Good. So its working as expected.

Re: QLinearGradient not working

PostPosted: Wed Oct 09, 2013 4:17 am
by maschoen
Let me add, if you'd like to try 4.8.2, I can provide the changes to allow it to compile under 6.5 for x86.

Mitchell

Re: QLinearGradient not working

PostPosted: Wed Oct 09, 2013 12:47 pm
by Noir
Thx for the tests :)
It is indeed what I wanted to display.

I already have a library for 4.8.2 armv7
Image
and some other binaries from
http://community.qnx.com/sf/discussion/do/listPosts/projects.qt/discussion.general.topc21389;jsessionid=E3FA15D8974480409CD820E640DC7374?pageSize=-1#post_post91093
but I am still a beginner with QNX and I don´t know what to do with these files..

What I already tried:
- copy files an binaries to \QNX650\target\qnx6\armle-v7\usr\lib and compile a qt4.8 program -> "make" command is not working because of some missing references
- copy only the lib-files to the path -> makefile after "make"-command indicates that it is still qt4.7
("make" command with the provided qmake_qnx-file found on foundry27)