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.7k 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 Offline
    B Offline
    bask185
    wrote on last edited by
    #1

    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 1 Reply Last reply
    0
    • 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