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 to create in QT main chat windows like this?
Forum Updated to NodeBB v4.3 + New Features

How to create in QT main chat windows like this?

Scheduled Pinned Locked Moved Unsolved General and Desktop
31 Posts 2 Posters 5.1k Views 1 Watching
  • 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.
  • Q Offline
    Q Offline
    qwe3
    wrote on last edited by qwe3
    #1

    Hello,

    I would like to create GUI for chat with other person.

    I would like something like that:

    example.png

    I have a problem with the main Window ( there are text messages: "Hi!" , "How are you?" ).

    I think I have to use QLabel with setStyleSheet and set background-color to yellow. But how Can I add QLabel to QWidget like QTableView?

    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #2

      Hi
      While it is possible to insert say a QLabel on top of a cell in a Table/ListView, it
      becomes heavy quite fast if you got many "chats"

      The better solution is to use a Delegate.
      https://doc.qt.io/qt-5/model-view-programming.html
      (Delegate Classes)

      Here is some samples
      https://stackoverflow.com/questions/1956542/how-to-make-item-view-render-rich-html-text-in-qt
      https://gist.github.com/niklasf/6124645

      You can also have a look at a real chat app ( written in Qt)
      https://github.com/telegramdesktop/tdesktop

      For the network part/sending text etc. i would use
      https://wiki.qt.io/WIP-How_to_create_a_simple_chat_application

      1 Reply Last reply
      3
      • Q Offline
        Q Offline
        qwe3
        wrote on last edited by qwe3
        #3

        @mrjj Thank you.

        I check Delegate and I think this isn't what I want. Of course I can add QLabel to QTableView, but when I click on QLabel I see the QTableView's cell. I setShowGrid to false but this isn't what I need.

        I check this chat app tdesktop. This application is WOW, but at this moment it's too hard and too big for me to understand and find where is QLabel with text's messages ( or something what do the same ).

        EDIT:

        I try with delegate and it may works.

        mrjjM 1 Reply Last reply
        0
        • Q qwe3

          @mrjj Thank you.

          I check Delegate and I think this isn't what I want. Of course I can add QLabel to QTableView, but when I click on QLabel I see the QTableView's cell. I setShowGrid to false but this isn't what I need.

          I check this chat app tdesktop. This application is WOW, but at this moment it's too hard and too big for me to understand and find where is QLabel with text's messages ( or something what do the same ).

          EDIT:

          I try with delegate and it may works.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @qwe3
          Telegram uses a delegate.
          Delegate is for custom drawing.
          But it also controls the editing via CreateEditor function.
          So you can program it to work as you wish.

          • of course I can add QLabel to QTableView
            Did you expect to type into the QLabel ?

          • but when I click on QLabel I see the QTableView's cell.

          Im not sure i follow?
          QLabel is non editable normally so that is expected.
          You cannot directly type to it.

          1 Reply Last reply
          1
          • Q Offline
            Q Offline
            qwe3
            wrote on last edited by qwe3
            #5

            @mrjj I wrote "I can add QLabel to QTableView". This is wrong. Now my code is very strange - I try do something good.

            My class delegate:

            delegate::delegate()
            {
            
            }
            
            QWidget *delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
            {
                    QLabel *label = new QLabel( parent);
                    label->setStyleSheet("QLabel {background-color:red}");
                    return label;
            }
            
            void delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
            {
                    QLabel *label = static_cast<QLabel *>(editor);
                    label->setText(index.data().toString());
            }
            
            void delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
            {
                QLabel *label = static_cast<QLabel *>(editor);
                label->setText("abcde");
                model->setData(index, index.data());
            }
            
            void delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
            {
                editor->setGeometry(option.rect);
            }
            
            void delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
            {
            
            }
            
            

            I find in youtube movie about Qt Delegate and rewrite the code and try change it to my needs.

            My mainApp:

                table = new QTableView(this);
                deleg = new delegate;
                table->setGeometry(0,0,500,500);
                model = new QStandardItemModel(10,2, this);
                item = new QStandardItem("somethingABC");
                model->setItem(0,0,item);
            
                table->setModel(model);
                for(int i=0;i<100;i++)
                    model->appendRow(QList<QStandardItem *>());
            
                table->setItemDelegate(deleg);
                table->setShowGrid(false);
                table->verticalHeader()->hide();
                table->horizontalHeader()->hide();
                table->setColumnWidth(0,250);
                table->setColumnWidth(1,250);
            

            When I double click on first cel ( 0,0 ) I get red rectangle with text "somethingABC". I would like to have this text when I execute the app ( no when I double click in QTableView ).

            EDIT:

            I would like something like:
            After 5 sec ( I can use QTimer and timeout()) I would like to add to my QTableView new QLabel in color red with text ( for example "Hello!" ) and this QLabel I would like to be rounded ( I know I can use setStyleSheet ).

            I would like to create GUI like in first post.

            1 Reply Last reply
            0
            • mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              Hi
              2 things that caught my eye.

              1:

              void delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
              {
                  QLabel *label = static_cast<QLabel *>(editor);
                  label->setText("abcde");
                  model->setData(index, index.data());
              }
              This function writes back the data to the model. You write back the same data
              so not sure what you do with label :) 
              

              2:
              You are not painting anything. (no code)

              void delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
              {
              call base class paint here or simply delete it if you have no need for extra paitning
              }
              
              

              Hi
              Did you read about Delegates ?
              The Editor is only active when editing, rest of the time its not shown.
              Then its paint job to show the data.

              1 Reply Last reply
              1
              • Q Offline
                Q Offline
                qwe3
                wrote on last edited by
                #7

                @mrjj Yes, I read about editor. But my problem is: I don't know what can I write in paint. I have 3 args: painter, option and index. I don't access to QLabel which I create in createEditor() function.

                mrjjM 1 Reply Last reply
                0
                • Q qwe3

                  @mrjj Yes, I read about editor. But my problem is: I don't know what can I write in paint. I have 3 args: painter, option and index. I don't access to QLabel which I create in createEditor() function.

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @qwe3
                  Ok. its important to read the docs as the Delegate follow a system so
                  one has to understand how it acts.

                  In paint you have access to the model which has the data.
                  So you can use QPainter and drawText to draw it. Also make it red if needed etc.
                  The QLabel you use is for Editing and not display.

                  1 Reply Last reply
                  1
                  • Q Offline
                    Q Offline
                    qwe3
                    wrote on last edited by
                    #9

                    @mrjj Okay. But Can I create text in red background which is in rounded background by QPainter. I never do something like that :)

                    mrjjM 1 Reply Last reply
                    0
                    • Q qwe3

                      @mrjj Okay. But Can I create text in red background which is in rounded background by QPainter. I never do something like that :)

                      mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by mrjj
                      #10

                      @qwe3
                      Yes all StyleSheet and Widgets use QPainter internally.
                      So you can make look like anything you like.

                      https://stackoverflow.com/questions/29196610/qt-drawing-a-filled-rounded-rectangle-with-border

                      QPainter p(this);
                      p.setRenderHint(QPainter::Antialiasing);
                      QPainterPath path;
                      path.addRoundedRect(QRectF(10, 10, 100, 50), 10, 10);  
                      QPen pen(Qt::black, 10);
                      p.setPen(pen);
                      p.fillPath(path, Qt::red);
                      p.drawPath(path);
                      

                      Do note the cell area is in option.rect
                      so you have to use its values to draw the right place. else you draw somewhere else on the view :)

                      1 Reply Last reply
                      1
                      • Q Offline
                        Q Offline
                        qwe3
                        wrote on last edited by
                        #11

                        @mrjj Now I add to paint() function:

                            QPen pen(Qt::black, 1);
                            painter->setPen(pen);
                            painter->drawText(0,0,100,100,0,index.data().toString());
                        

                        and it works!

                        But I see next 2 problems:

                        1. I have to write 100,100 in drawText() function. Is there any way to get size which my index.data().toString() needs?

                        2. When I add this lines to my paint() function I only see this text in first cell (0,0).

                        I have:

                            item = new QStandardItem("somethingABC");
                            item2 = new QStandardItem("somethingABC");
                            item3 = new QStandardItem("somethingABC");
                            model->setItem(0,0,item);
                            model->setItem(1,0,item2);
                            model->setItem(2,0,item3);
                        

                        So I think I have to get 3 texts "somethingABC" in my QTableView. Right?

                        mrjjM 1 Reply Last reply
                        0
                        • Q qwe3

                          @mrjj Now I add to paint() function:

                              QPen pen(Qt::black, 1);
                              painter->setPen(pen);
                              painter->drawText(0,0,100,100,0,index.data().toString());
                          

                          and it works!

                          But I see next 2 problems:

                          1. I have to write 100,100 in drawText() function. Is there any way to get size which my index.data().toString() needs?

                          2. When I add this lines to my paint() function I only see this text in first cell (0,0).

                          I have:

                              item = new QStandardItem("somethingABC");
                              item2 = new QStandardItem("somethingABC");
                              item3 = new QStandardItem("somethingABC");
                              model->setItem(0,0,item);
                              model->setItem(1,0,item2);
                              model->setItem(2,0,item3);
                          

                          So I think I have to get 3 texts "somethingABC" in my QTableView. Right?

                          mrjjM Offline
                          mrjjM Offline
                          mrjj
                          Lifetime Qt Champion
                          wrote on last edited by mrjj
                          #12

                          @qwe3 said in How to create in QT main chat windows like this?:

                          1
                          The cell area is in option.rect. (one of the parameters to paint)
                          2:
                          i think its related to 1 as all cells then paint its text in 100,100 :)

                          painter->drawText(option.rect, index.data().toString());

                          1 Reply Last reply
                          1
                          • Q Offline
                            Q Offline
                            qwe3
                            wrote on last edited by
                            #13

                            @mrjj One line and 2 problems aren't now problems :D Perfect!

                            mrjjM 1 Reply Last reply
                            1
                            • Q qwe3

                              @mrjj One line and 2 problems aren't now problems :D Perfect!

                              mrjjM Offline
                              mrjjM Offline
                              mrjj
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @qwe3
                              Super.
                              Delegates are a bit complicated to begin with but later you love them as you can do anything you like.
                              and then have good performance too \o/

                              1 Reply Last reply
                              0
                              • Q Offline
                                Q Offline
                                qwe3
                                wrote on last edited by
                                #15

                                @mrjj I create rounded rectangle and it works :)

                                But I don't know how can I do the last thing:

                                The message text can be longer than one line. I think I have to change row's height. This is not a problem: table->setRowHeight(1,240);

                                But when I have to do that? In delegate functions()?

                                mrjjM 1 Reply Last reply
                                0
                                • Q qwe3

                                  @mrjj I create rounded rectangle and it works :)

                                  But I don't know how can I do the last thing:

                                  The message text can be longer than one line. I think I have to change row's height. This is not a problem: table->setRowHeight(1,240);

                                  But when I have to do that? In delegate functions()?

                                  mrjjM Offline
                                  mrjjM Offline
                                  mrjj
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #16

                                  @qwe3
                                  Hi
                                  Nope, its not the delegates job
                                  if its for all rows then

                                  QHeaderView *verticalHeader = myTableView->verticalHeader();
                                  verticalHeader->setSectionResizeMode(QHeaderView::Fixed);
                                  verticalHeader->setDefaultSectionSize(24);
                                  
                                  1 Reply Last reply
                                  1
                                  • Q Offline
                                    Q Offline
                                    qwe3
                                    wrote on last edited by
                                    #17

                                    @mrjj Thank you! I have to change your code to:

                                    verticalHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
                                    

                                    But you helped me next time! :)

                                    Thank you

                                    mrjjM 1 Reply Last reply
                                    0
                                    • Q qwe3

                                      @mrjj Thank you! I have to change your code to:

                                      verticalHeader->setSectionResizeMode(QHeaderView::ResizeToContents);
                                      

                                      But you helped me next time! :)

                                      Thank you

                                      mrjjM Offline
                                      mrjjM Offline
                                      mrjj
                                      Lifetime Qt Champion
                                      wrote on last edited by
                                      #18

                                      @qwe3
                                      Hi
                                      Super.
                                      Congratulation on your first Delegate.

                                      1 Reply Last reply
                                      0
                                      • Q Offline
                                        Q Offline
                                        qwe3
                                        wrote on last edited by qwe3
                                        #19

                                        @mrjj Only in 50%.

                                        I need one more:

                                        QWidget *delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
                                        {
                                            return nullptr;
                                        }
                                        
                                        void delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
                                        {
                                            editor->setGeometry(option.rect);
                                        }
                                        
                                        void delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
                                        {
                                            if(index.row()%2==0 && index.column()!=1)
                                            {
                                                QPen pen2(Qt::yellow, 1);
                                                painter->setPen(pen2);
                                            
                                                QPainterPath path;
                                                path.addRoundedRect(QRectF(option.rect), 10, 10);
                                                painter->fillPath(path, Qt::yellow);
                                                painter->drawPath(path);
                                                QPen pen(Qt::black, 1);
                                                painter->setPen(pen);
                                                painter->drawText(option.rect,Qt::AlignCenter, index.data().toString());
                                            }
                                        }
                                        

                                        I would like to select text message, click on it right mouse button, get the list, where is "copy" and other possibilities. How can I do this?

                                        Now I can't select text and click right mouse button

                                        1 Reply Last reply
                                        0
                                        • mrjjM Offline
                                          mrjjM Offline
                                          mrjj
                                          Lifetime Qt Champion
                                          wrote on last edited by
                                          #20

                                          Hi
                                          For right click menu you can use a context menu

                                          https://forum.qt.io/topic/31233/how-to-create-a-custom-context-menu-for-qtableview/8

                                          1 Reply Last reply
                                          1

                                          • Login

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