Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Own keyboard doesn't work well on raspberry.
Forum Updated to NodeBB v4.3 + New Features

Own keyboard doesn't work well on raspberry.

Scheduled Pinned Locked Moved Solved Mobile and Embedded
6 Posts 3 Posters 422 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.
  • D Offline
    D Offline
    Dankal
    wrote on last edited by Dankal
    #1

    Hi, I wrote simply screen keyboard which shows when QTextEdit has focus. In window where I want to input chars i have loop:

    void LoginScreen::loop()
    {
        while(this->isVisible())
        {
            if(ui->login->hasFocus())
            {
                keyboard->activate(ui->login, ui->loginButton);
                keyboard->show();
                keyboard->activateWindow();
                keyboard->raise();
            }
            else if(ui->password->hasFocus())
            {
                keyboard->activate(ui->password, ui->loginButton);
                keyboard->show();
                keyboard->activateWindow();
                keyboard->raise();
            }
            qApp->processEvents();
        }
    }
    

    To close keyboard when user clicks somewhere else i wrote:

    void LoginScreen::mousePressEvent(QMouseEvent *event)
    {
        ui->label->setFocus();
        keyboard->hide();
    }
    

    Keyboard class (singleton):

    Keyboard* Keyboard::instance = nullptr;
    
    Keyboard::Keyboard(QWidget *parent) :
        QDialog(parent),
        ui(new Ui::Keyboard)
    {
        ui->setupUi(this);
        setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
        ile++;
    }
    
    Keyboard::~Keyboard()
    {
        delete ui;
        ile--;
    }
    
    Keyboard* Keyboard::getKeyboard()
    {
        if(!instance)
        {
            instance = new Keyboard();
        }
        return instance;
    }
    
    void Keyboard::activate(QLineEdit *toEdit, QPushButton *toClick)
    {
        this->toClick = toClick;
        this->toEdit = toEdit;
        if(toEdit->echoMode() == 2)
        {
            this->type = 0;
            on_SWITCH_clicked();
        }
        else if(toEdit->text().size()==0)
        {
            this->type = 2;
            on_SWITCH_clicked();
        }
        else if(toEdit->text().size() > 0)
        {
            this->type = 0;
            on_SWITCH_clicked();
        }
    }
    
    void Keyboard::on_Q_clicked()
    {
        toEdit->insert(ui->Q->text());
        if(toEdit->text().size()==1)
        {
            this->type = 0;
            on_SWITCH_clicked();
        }
    }
    
    etc...
    

    So, when i click login lineEdit my keyboard shows and everythink works good. When i click background keybords hides and shows when i click some of lineEdit. But, when I have focused login lineEdit, and then I click password lineEdit it sometimes change focus after one click, sometimes i have to click again. Before i added Qt::WindowStaysOnTopHint on keyboard window everytime i had to click twice to change focused lineEdit. I don't have any idea why it's happening on Raspberry Pi 3B with Raspbian, on windows 10 everythink works perfect even without Qt::WindowStaysOnTopHint. BTW, is there any way to keep Cursor on lineEdit when i shows my keyboard? Now I change background in styleSheet from white to grey to see where am i writing.

    qtvirtualkeyboard is not an option.

    J.HilkJ 1 Reply Last reply
    0
    • D Dankal

      Hi, I wrote simply screen keyboard which shows when QTextEdit has focus. In window where I want to input chars i have loop:

      void LoginScreen::loop()
      {
          while(this->isVisible())
          {
              if(ui->login->hasFocus())
              {
                  keyboard->activate(ui->login, ui->loginButton);
                  keyboard->show();
                  keyboard->activateWindow();
                  keyboard->raise();
              }
              else if(ui->password->hasFocus())
              {
                  keyboard->activate(ui->password, ui->loginButton);
                  keyboard->show();
                  keyboard->activateWindow();
                  keyboard->raise();
              }
              qApp->processEvents();
          }
      }
      

      To close keyboard when user clicks somewhere else i wrote:

      void LoginScreen::mousePressEvent(QMouseEvent *event)
      {
          ui->label->setFocus();
          keyboard->hide();
      }
      

      Keyboard class (singleton):

      Keyboard* Keyboard::instance = nullptr;
      
      Keyboard::Keyboard(QWidget *parent) :
          QDialog(parent),
          ui(new Ui::Keyboard)
      {
          ui->setupUi(this);
          setWindowFlags(Qt::Window | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
          ile++;
      }
      
      Keyboard::~Keyboard()
      {
          delete ui;
          ile--;
      }
      
      Keyboard* Keyboard::getKeyboard()
      {
          if(!instance)
          {
              instance = new Keyboard();
          }
          return instance;
      }
      
      void Keyboard::activate(QLineEdit *toEdit, QPushButton *toClick)
      {
          this->toClick = toClick;
          this->toEdit = toEdit;
          if(toEdit->echoMode() == 2)
          {
              this->type = 0;
              on_SWITCH_clicked();
          }
          else if(toEdit->text().size()==0)
          {
              this->type = 2;
              on_SWITCH_clicked();
          }
          else if(toEdit->text().size() > 0)
          {
              this->type = 0;
              on_SWITCH_clicked();
          }
      }
      
      void Keyboard::on_Q_clicked()
      {
          toEdit->insert(ui->Q->text());
          if(toEdit->text().size()==1)
          {
              this->type = 0;
              on_SWITCH_clicked();
          }
      }
      
      etc...
      

      So, when i click login lineEdit my keyboard shows and everythink works good. When i click background keybords hides and shows when i click some of lineEdit. But, when I have focused login lineEdit, and then I click password lineEdit it sometimes change focus after one click, sometimes i have to click again. Before i added Qt::WindowStaysOnTopHint on keyboard window everytime i had to click twice to change focused lineEdit. I don't have any idea why it's happening on Raspberry Pi 3B with Raspbian, on windows 10 everythink works perfect even without Qt::WindowStaysOnTopHint. BTW, is there any way to keep Cursor on lineEdit when i shows my keyboard? Now I change background in styleSheet from white to grey to see where am i writing.

      qtvirtualkeyboard is not an option.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #2

      @Dankal you my dear friend are a maniac by implementing your keyboard this way one core is running on full blast all the time when the keyboard is visible.

      No wonder the pi stumbles with this.

      Whats that loop supposed to do anyway?


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      D 1 Reply Last reply
      1
      • J.HilkJ J.Hilk

        @Dankal you my dear friend are a maniac by implementing your keyboard this way one core is running on full blast all the time when the keyboard is visible.

        No wonder the pi stumbles with this.

        Whats that loop supposed to do anyway?

        D Offline
        D Offline
        Dankal
        wrote on last edited by Dankal
        #3

        @J-Hilk Because QLineEdit has no "clicked()" slot, I came up with a replacement for searching if this field has focus, in summary it's a replacement for clicked() to bring up the keyboard when user wants to enter text :)

        Pi does not look like it has a problem with this loop, as I mentioned the combination QLineEdit -> background -> QLineEdit works fine every time, I thought it was a matter of window settings, because the window manager in Windows and Linux I guessing is different

        J.HilkJ 1 Reply Last reply
        0
        • D Dankal

          @J-Hilk Because QLineEdit has no "clicked()" slot, I came up with a replacement for searching if this field has focus, in summary it's a replacement for clicked() to bring up the keyboard when user wants to enter text :)

          Pi does not look like it has a problem with this loop, as I mentioned the combination QLineEdit -> background -> QLineEdit works fine every time, I thought it was a matter of window settings, because the window manager in Windows and Linux I guessing is different

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by J.Hilk
          #4

          @Dankal overwrite the https://doc.qt.io/qt-5/qwidget.html#focusInEvent and https://doc.qt.io/qt-5/qwidget.html#focusOutEvent (its the base class) and show /hide your keyboard according to this


          if this doesn't work quite right, it's been a while since I made this myself, than overwrite the QEvent function itself, that one is definitely called


          #ifndef MYLINEEDIT_H
          #define MYLINEEDIT_H
          
          #include <QLineEdit>
          #include <QEvent>
          #include <QDebug>
          
          class MyLineEdit : public QLineEdit
          {
              Q_OBJECT
          public:
              explicit MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent)
              {
                  connect(this, &MyLineEdit::focusInSignal, this, []()->void{qDebug() << "Focus in event";});
                  connect(this, &MyLineEdit::focusOutSignal, this, []()->void{qDebug() << "Focus out event";});
              }
          
          signals:
              void focusInSignal();
              void focusOutSignal();
          
          protected:
              virtual bool event(QEvent *event) override {
                  if (event->type() == QEvent::FocusIn)
                      emit focusInSignal();
                  if(event->type() == QEvent::FocusOut)
                      emit focusOutSignal();
                  return  QLineEdit::event(event);
              }
          
          };
          
          #endif // MYLINEEDIT_H
          
          

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          D 1 Reply Last reply
          1
          • J.HilkJ J.Hilk

            @Dankal overwrite the https://doc.qt.io/qt-5/qwidget.html#focusInEvent and https://doc.qt.io/qt-5/qwidget.html#focusOutEvent (its the base class) and show /hide your keyboard according to this


            if this doesn't work quite right, it's been a while since I made this myself, than overwrite the QEvent function itself, that one is definitely called


            #ifndef MYLINEEDIT_H
            #define MYLINEEDIT_H
            
            #include <QLineEdit>
            #include <QEvent>
            #include <QDebug>
            
            class MyLineEdit : public QLineEdit
            {
                Q_OBJECT
            public:
                explicit MyLineEdit(QWidget *parent = nullptr) : QLineEdit(parent)
                {
                    connect(this, &MyLineEdit::focusInSignal, this, []()->void{qDebug() << "Focus in event";});
                    connect(this, &MyLineEdit::focusOutSignal, this, []()->void{qDebug() << "Focus out event";});
                }
            
            signals:
                void focusInSignal();
                void focusOutSignal();
            
            protected:
                virtual bool event(QEvent *event) override {
                    if (event->type() == QEvent::FocusIn)
                        emit focusInSignal();
                    if(event->type() == QEvent::FocusOut)
                        emit focusOutSignal();
                    return  QLineEdit::event(event);
                }
            
            };
            
            #endif // MYLINEEDIT_H
            
            
            D Offline
            D Offline
            Dankal
            wrote on last edited by
            #5

            @J-Hilk Thank you so much, I had no idea it could be done that way. What I did:

                ui->login->installEventFilter(this);
                ui->password->installEventFilter(this);
            
            ...
            
            bool LoginScreen::eventFilter(QObject *obj, QEvent *event)
            {
                if( obj == ui->login && event->type() == QEvent::FocusIn)
                {
                    ui->login->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(200, 200, 200);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                    ui->password->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                    keyboard->activate(ui->login, ui->loginButton);
                    keyboard->show();
                    keyboard->activateWindow();
                    return false;
                }
                else if( obj == ui->password && event->type() == QEvent::FocusIn)
                {
                    ui->password->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(200, 200, 200);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                    ui->login->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                    keyboard->activate(ui->password, ui->loginButton);
                    keyboard->show();
                    keyboard->activateWindow();
                    return false;
                }
            }
            

            Now it works as it should, thank you again :)

            Pablo J. RoginaP 1 Reply Last reply
            1
            • D Dankal

              @J-Hilk Thank you so much, I had no idea it could be done that way. What I did:

                  ui->login->installEventFilter(this);
                  ui->password->installEventFilter(this);
              
              ...
              
              bool LoginScreen::eventFilter(QObject *obj, QEvent *event)
              {
                  if( obj == ui->login && event->type() == QEvent::FocusIn)
                  {
                      ui->login->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(200, 200, 200);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                      ui->password->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                      keyboard->activate(ui->login, ui->loginButton);
                      keyboard->show();
                      keyboard->activateWindow();
                      return false;
                  }
                  else if( obj == ui->password && event->type() == QEvent::FocusIn)
                  {
                      ui->password->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(200, 200, 200);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                      ui->login->setStyleSheet("color: rgb(0, 0, 0);background-color: rgb(255, 255, 255);font: 75 30pt \"Tahoma\";border-style: solid;border-width:4px;border-radius:30px;");
                      keyboard->activate(ui->password, ui->loginButton);
                      keyboard->show();
                      keyboard->activateWindow();
                      return false;
                  }
              }
              

              Now it works as it should, thank you again :)

              Pablo J. RoginaP Offline
              Pablo J. RoginaP Offline
              Pablo J. Rogina
              wrote on last edited by
              #6

              @Dankal said in Own keyboard doesn't work well on raspberry.:

              Now it works as it should

              great, please don't forget to mark your post as solved!

              Upvote the answer(s) that helped you solve the issue
              Use "Topic Tools" button to mark your post as Solved
              Add screenshots via postimage.org
              Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

              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