Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How can you display text with different colors?
Forum Updated to NodeBB v4.3 + New Features

How can you display text with different colors?

Scheduled Pinned Locked Moved Unsolved General and Desktop
12 Posts 2 Posters 4.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B bask185

    I am almost done with my GUI applications. So far I can send, read and handle bytes over the serial ports. All my buttons do that they must do and I have a functioning keyboard. There is only one thing which I still need to do and that is displaying the text. At the moment my GUI looks like:
    alt text
    That black thing needs to be my display it is an OpenGlWidget. I used it because it is black and I do not know any better.

    On this display I want to show 40 x 16 characters.. with different colours (20 to be exact).
    There are 5 different displays of which only 1 is shown. The machines which will controll this display can fill the 5 screens with text in the background while displaying one of them. This is not what I have thought of, this is how our machine <> HMI protocol simply is.

    The machine can send instructions like placing the cursor or placing text at the cursor. I already have implemented most of these instructions. I'll show one example of how I can set a lettre:

    if(b > 31 && b < 128 && COMMAND == false) {                                         // if received bytes are > 31 and < 127 AND if the COMMAND flag is false, the byte is treated as a to be printed character
                lettre[index1][column[index1]++][row[index1]] = (char)b;
                                                                                                 // stuffs the character in the text array with the active color.
                qDebug() <<"lettre received";
              }
    

    Principle is simple, I have a 3D array 'lettre' : char lettre[5][40][16]; first index is the screen index, 2nd and 3rd are column and rows respectively. I also have 5x 1D arrays for the columns and letters. So in the code I simply set a lettre on the #index1' screen on column[index1] and row [index1]. And I increase the column[index] by 1. I also have a variable 'index2' and index2 will be used for displaying 1 of the 5 displays.

    But what is the best way to display the text on the screen? I was thinking of using 16 textlabels but I simply do not know the syntax of Qt well enough. I don't know how I can give every letter a different color. I suppose I would also need a 3D array to store color indices in. And I really need a black background for the display. I also need a cursor (colored rectangle) which the machine can turn on and of (setting a bool val in the program)

    In my prescious program processing I simply made 5 display objects each display object would have a 2D array containing 40x16 lettre objects and each lettre object has 2 arguement, character and color index. Ez Pz right? But dat java embedded thing is just too heavy for my Raspberry :(

    So I would like some advice in what widgets to use, how I can implement the colors and I can get me a cursor.

    this is how it looks like in processing
    alt text

    VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #2

    @bask185 said in How can you display text with different colors?:

    That black thing needs to be my display it is an OpenGlWidget. I used it because it is black and I do not know any better.

    The background colour is not a great way of choosing what widget to use. You can use stylesheets to customise the background colour of any widget

    On this display I want to show 40 x 16 characters

    Looks like a table to me, use QTableView + QStandardItemModel? (ok, yes, you can use QTableWidget but I hate that thing)
    You can set the Qt::ForegroundRole data to chose the text colour and the Qt::BackgroundRole data to implement the cursor (If I understood correctly the "cursor" is just setting the background of a specific letter, correct?)

    Before I can move on writing some code examples I'd need to understand what you mean by "screen" are they 5 things side by side or is it a totally different view?


    Looking at your images it'd look like you did not apply a layout to your widget. You should otherwise you won't be able to allow basic operations as a window resizing. Use spacers to leave gaps and then lay out your widget in a grid (or nested layouts)

    Probably irrelevant:

    I want to show [...] characters [...] char lettre

    character != char. In 2017 we can't be stuck with ASCII.

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    B 1 Reply Last reply
    2
    • VRoninV VRonin

      @bask185 said in How can you display text with different colors?:

      That black thing needs to be my display it is an OpenGlWidget. I used it because it is black and I do not know any better.

      The background colour is not a great way of choosing what widget to use. You can use stylesheets to customise the background colour of any widget

      On this display I want to show 40 x 16 characters

      Looks like a table to me, use QTableView + QStandardItemModel? (ok, yes, you can use QTableWidget but I hate that thing)
      You can set the Qt::ForegroundRole data to chose the text colour and the Qt::BackgroundRole data to implement the cursor (If I understood correctly the "cursor" is just setting the background of a specific letter, correct?)

      Before I can move on writing some code examples I'd need to understand what you mean by "screen" are they 5 things side by side or is it a totally different view?


      Looking at your images it'd look like you did not apply a layout to your widget. You should otherwise you won't be able to allow basic operations as a window resizing. Use spacers to leave gaps and then lay out your widget in a grid (or nested layouts)

      Probably irrelevant:

      I want to show [...] characters [...] char lettre

      character != char. In 2017 we can't be stuck with ASCII.

      B Offline
      B Offline
      bask185
      wrote on last edited by
      #3

      @VRonin said in How can you display text with different colors?:

      Before I can move on writing some code examples I'd need to understand what you mean by "screen" are they 5 things side by side or is it a totally different view?

      a 'screen' is that big black box with 40 x 16 characters you can see on the screen shots. There are 5 of those, but only 1 can be visually displayed at the time due to the available space. The machine can send an instruction which tells the GUI which of the 5 displays is to be shown, therefor I used the variable index2. In processing code is:

      display[index2].paint(); //  0 <= index2 <5
      

      And I indeed have not used any layouts because I am dealing with a fixed resolution, so I did not think I would need the layouts. We simply buy touchmonitors with a 4:3 display ratio and we set our raspberries at 1024 x 768 pixels.

      Probably irrelevant:
      
      I want to show [...] characters [...] char lettre
      character != char. In 2017 we can't be stuck with ASCII.
      

      Yeah, it kinda is ;) The protocol we are working with works with ASCII characters, nothing I can do about it

      B 1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by VRonin
        #4

        Ok, create 5 QTableWidgets (I'll leave it up to you how you switch from one to the other, QStackedWidget?) and get rid of lettre array.
        declare a private QTableWidgets *monitors[] = {ui->tableWidget1, ui->tableWidget2, ui->tableWidget3, ui->tableWidget4, ui->tableWidget5};

        then in the constructor add:

        for(QTableWidgets* monitor : monitors){
        monitor->setRowCount(40);
        monitor->setColumnCount(16);
        }
        

        now you can use:

        • to set the letter content
        // char b
        monitors[index1]->model()->setData(monitors[index1]->model()->index(column[index1],row[index1]),QChar(b));
        
        • to set the letter colour (here blue)
        monitors[index1]->model()->setData(monitors[index1]->model()->index(column[index1],row[index1]),QBrush(Qt::blue),Qt::ForegroundRole);
        
        • to set the background colour for the letter (here blue):
        monitors[index1]->model()->setData(monitors[index1]->model()->index(column[index1],row[index1]),QBrush(Qt::blue),Qt::BackgroundRole);
        
        • to reset the colours to the default replace QBrush(...) with QVariant()

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        0
        • B bask185

          @VRonin said in How can you display text with different colors?:

          Before I can move on writing some code examples I'd need to understand what you mean by "screen" are they 5 things side by side or is it a totally different view?

          a 'screen' is that big black box with 40 x 16 characters you can see on the screen shots. There are 5 of those, but only 1 can be visually displayed at the time due to the available space. The machine can send an instruction which tells the GUI which of the 5 displays is to be shown, therefor I used the variable index2. In processing code is:

          display[index2].paint(); //  0 <= index2 <5
          

          And I indeed have not used any layouts because I am dealing with a fixed resolution, so I did not think I would need the layouts. We simply buy touchmonitors with a 4:3 display ratio and we set our raspberries at 1024 x 768 pixels.

          Probably irrelevant:
          
          I want to show [...] characters [...] char lettre
          character != char. In 2017 we can't be stuck with ASCII.
          

          Yeah, it kinda is ;) The protocol we are working with works with ASCII characters, nothing I can do about it

          B Offline
          B Offline
          bask185
          wrote on last edited by
          #5

          @VRonin said in How can you display text with different colors?:

          declare a private QTableWidgets *monitors[] = {ui->tableWidget1, ui->tableWidget2, ui->tableWidget3, ui->tableWidget4, ui->tableWidget5};

          I am having troubles with this one. I tried both in MainWindow.ccp and in MainWindow.h in the private section looking like this

          #ifndef MAINWINDOW_H
          #define MAINWINDOW_H
          
          #include <QMainWindow>
          #include "keyboard.h"
          #include "numpad.h"
          #include <QTableWidget>
          
          
          namespace Ui {
          class MainWindow;
          }
          
          class MainWindow : public QMainWindow
          {
              Q_OBJECT
          
          public:
              explicit MainWindow(QWidget *parent = 0);
              ~MainWindow();
          
          private slots:
              void serialReceived();
              void send(QString c);
          
              void on_F1_clicked();
             // many more buttons...
          
          private:
              Ui::MainWindow *ui;
              Keyboard *Kboard;
              Numpad *numpad;
              QTableWidget *monitors[] = {ui->tableWidget1, ui->tableWidget2, ui->tableWidget3, ui->tableWidget4, ui->tableWidget5};
          };
          
          #endif // MAINWINDOW_H
          

          error message:

          C:\Users\sknippels\Documents\GUI\mainwindow.h:64: error: invalid use of incomplete type 'class Ui::MainWindow'
               QTableWidget *monitors[] = {ui->tableWidget1, ui->tableWidget2, ui->tableWidget3, ui->tableWidget4, ui->tableWidget5};
                                             ^
          

          I included the <QTableWidget> library

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #6

            You have to get rid of the OpenGL widget and put the widgets somewhere in Qt Designer. the names I used ui->tableWidget1 are just examples, use the names you set in designer

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            1 Reply Last reply
            0
            • B Offline
              B Offline
              bask185
              wrote on last edited by bask185
              #7

              Ok i get it, I only have one small issue left. At first I declared and initialized the array in the constructor. But that gave me the problem that I could not acces it in functions outside the constructor. Than I tried doing it with the rest of the global variables but there it does not reckognize the 'ui' (ui is not declared in this scope). And then I tried declaring the array in the global variables

              #include <QTableWidget>
              
              QSerialPort *serial;        // global variables
              QTableWidget *monitors[5];
              

              and initialize it in the constructor

              monitors[] = {ui->tableWidget_1, ui->tableWidget_2, ui->tableWidget_3, ui->tableWidget_4, ui->tableWidget_5};
              
                 for(QTableWidget* monitor : monitors) {
                     monitor->setRowCount(16);
                     monitor->setColumnCount(40);
                 }
              

              But ofcourse :

              C:\Users\sknippels\Documents\GUI\mainwindow.cpp:72: error: expected primary-expression before ']' token
                  monitors[] = {ui->tableWidget_1, ui->tableWidget_2, ui->tableWidget_3, ui->tableWidget_4, ui->tableWidget_5};
                           ^
              

              so now I lost it -_-"

              EDIT:

              nvm this fixed it:

               monitors[0] = ui->tableWidget_1;
                 monitors[1] = ui->tableWidget_2;
                 monitors[2] = ui->tableWidget_3;
                 monitors[3] = ui->tableWidget_4;
                 monitors[4] = ui->tableWidget_5;
              
              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #8

                Do not use global variables unless vital.

                move QTableWidget *monitors[5]; in the private section of the class and add monitors({ui->tableWidget1, ui->tableWidget2, ui->tableWidget3, ui->tableWidget4, ui->tableWidget5}) to the constructor initialisation list

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  bask185
                  wrote on last edited by
                  #9

                  alt text The beginning is there.
                  Now I just have to figure out

                  • how to make the background black
                  • remove the grid and everything else I dont need :D

                  Thank you once again

                  VRoninV 1 Reply Last reply
                  0
                  • B bask185

                    alt text The beginning is there.
                    Now I just have to figure out

                    • how to make the background black
                    • remove the grid and everything else I dont need :D

                    Thank you once again

                    VRoninV Offline
                    VRoninV Offline
                    VRonin
                    wrote on last edited by VRonin
                    #10

                    @bask185 said in How can you display text with different colors?:

                    how to make the background black

                    in designer, select the table and find Style Sheet in the properties, edit it and put background: black

                    remove the grid and everything else I dont need :D

                    you can use the loop in the constructor to add:

                    for(QTableWidgets* monitor : monitors){
                    monitor->setRowCount(40);
                    monitor->setColumnCount(16);
                    monitor->setShowGrid(false);
                    monitor->horizontalHeader()->hide(); // requires #include <QHeaderView>
                    monitor->verticalHeader()->hide();
                    }
                    

                    you are free to set column and rows sizes as you prefer and you can use other roles to set other parameters. For example Qt::FontRole to adjust the font family, size and style or the Qt::TextAlignmentRole to decide how the text should align in the cell

                    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                    ~Napoleon Bonaparte

                    On a crusade to banish setIndexWidget() from the holy land of Qt

                    1 Reply Last reply
                    1
                    • B Offline
                      B Offline
                      bask185
                      wrote on last edited by bask185
                      #11

                      how can I make the boxes smaller? I found 2 functions which I implemented in the constructor's for-loop but it does not seem to have any effect at all:

                      monitor->rowHeight(1); // seems it does not matter what number I fill in
                      monitor->columnWidth(1);
                      

                      0_1490188419292_upload-05292dbf-13bb-44b3-8b3e-94dd907fdf37

                      I have read the Qt doc of Qtablewidget 3 times now but I cannot find it. And when I still had the grid I shrank all boxes to absolute mininum size but that was still too lare. I can only fit about 32 characters next to eachother. Is this fixable or should I just use text labels instead?

                      EDIT:
                      table->horizontalHeader()->setDefaultSectionSize(20);
                      table->verticalHeader()->setDefaultSectionSize(20); // Tnx google!

                      VRoninV 1 Reply Last reply
                      0
                      • B bask185

                        how can I make the boxes smaller? I found 2 functions which I implemented in the constructor's for-loop but it does not seem to have any effect at all:

                        monitor->rowHeight(1); // seems it does not matter what number I fill in
                        monitor->columnWidth(1);
                        

                        0_1490188419292_upload-05292dbf-13bb-44b3-8b3e-94dd907fdf37

                        I have read the Qt doc of Qtablewidget 3 times now but I cannot find it. And when I still had the grid I shrank all boxes to absolute mininum size but that was still too lare. I can only fit about 32 characters next to eachother. Is this fixable or should I just use text labels instead?

                        EDIT:
                        table->horizontalHeader()->setDefaultSectionSize(20);
                        table->verticalHeader()->setDefaultSectionSize(20); // Tnx google!

                        VRoninV Offline
                        VRoninV Offline
                        VRonin
                        wrote on last edited by
                        #12
                        table->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
                        table->verticalHeader()->setSectionResizeMode(QHeaderView::Fixed);
                        table->horizontalHeader()->resizeSections(20);
                        table->verticalHeader()->resizeSections(20);
                        

                        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                        ~Napoleon Bonaparte

                        On a crusade to banish setIndexWidget() from the holy land of Qt

                        1 Reply Last reply
                        0

                        • Login

                        • Login or register to search.
                        • First post
                          Last post
                        0
                        • Categories
                        • Recent
                        • Tags
                        • Popular
                        • Users
                        • Groups
                        • Search
                        • Get Qt Extensions
                        • Unsolved