PDA

View Full Version : virtual keyboard done with qt4-designer



Klaus_EAN
4th May 2007, 08:05
Hi there all!


Has anyone out there a "virtual keyboard" done with qt4-designer and can deliver the sources?
I need this for quick testing purposes.
The idea is to use this virtual or better software-keyboard to fire letters like A to Z, arrow up, Enter, Escape, plus etc. and do NOT use the hardware keyboard.
I found out that Designer accepts for push-buttons an icon that can be used (e.g. arrow up).

I have used the qt- and google-search but found only:
Qtopia has a so called virtual keyboard in Qtopia Phone and qtmail but no screenshot is available,
reading the instructions for getting and building the sources (?) you get nearly mad.
So the next questions come up: Can I use Qtopia on "normal" boxes (not on embedded systems) with Designer-help? Is there an abstraction-layer between the picture of the keyboard-layout and the sources?


I would be very happy to get in minimum a link for the icons for the layout (maybe a library?).



Thanks
Regards

Klaus

high_flyer
4th May 2007, 13:14
Can I use Qtopia on "normal" boxes (not on embedded systems) with Designer-help? I
You don't need that.
All you need are the classes (code), you can compile it with normal Qt4 then.
At worst, you will have minor adjustment to make to the code, if any.

The problem is not the gui - but the receiving end of the virtual keyboard.
Should the virtual keyboard only work inside its own program, or should it be "global" so that it will type in to other applications text boxes?

If its the first option, then what is the problem having a bunch of butons on a dialog sending KeyPressed events?

madhukiranmp
27th October 2010, 07:57
Hi, I have designed 12 screens for our project. Now our project needs virtual keyboard implementation. I downloaded virtual keyboard from the forum and added to my project.

I want to show the virtual keyboard whenever clicked on line edit. For this I've written one "eventFilter(QObject* call_object, QEvent* pevent)" function.

The VKB pop ups if I click on line edit, but the problem is, if I move the mouse pointer on the VKB the keyboard disappears and appears on the other screen.

and there if I click on any key the application terminates.

bool TME_COM::eventFilter(QObject* call_object, QEvent* pevent)
{


QLineEdit *isQLineEdit = static_cast<QLineEdit*>(call_object);

if(!isQLineEdit) return false;

if (pevent->type() == QEvent::MouseButtonPress)
{
;
virtualKeyBoard->show();
return true;

}else

return false;
}

this is the function I used. so, the questions are

can any body help, to solve these two problems(1.VKB appears on other screen and 2.program terminates if clicked on key on the other screen)

please reply as soon as possible.
Thanks in advance

high_flyer
27th October 2010, 13:11
isQLineEdit will always be true, even if its not a QLineEdit who sent the vent.
Which can casue all kinds of not wanted behavior.
Also, when using plymorphisem, you should not use static_cast, but dynamic_cast.
Actually static_cast is evil, and should not be used except for very few cases.

you should test it like this:


if( call_object != pLineEdit) return; //where pLineEdit is the pointer to the clicked line edit.

madhukiranmp
4th November 2010, 06:30
thanks for the reply, I tried with the above statement but it didn't work. I tried with using signals and slots as follows

connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(setWidgets(QWidget*, QWidget*)));

void TME_COM::setWidgets(QWidget * old, QWidget *newwid)
{
const char* ab;
if(newwid != 0)
{
ab = newwid->metaObject()->className();
qDebug(ab);
if(strcmp(ab,"QLineEdit")==0)
{
qDebug("focus on line edit\n");
virtualkeyboard->show();
}
else
{
virtualkeyboard->hide();
}
}
}

it worked, but I stuck with another problem.
Virtual keyboard is appearing with out title bar.

In virtual keyboard constructor, there is a statement like this
this->setWindowFlags(Qt::Tool);

If I remove this statement, the program is entering infinite loop and if I include the above statement VKB works, but appears without title bar.
I want to display VKB with title bar and it should work fine.

please help me.:(

high_flyer
4th November 2010, 09:37
thanks for the reply, I tried with the above statement but it didn't work.
Then you are doing something else wrong.
Testing for the object address MUST work.
Can you show the code you tried which didn't work?
The code you posted here is totally diferent than the one you posted with your question (different function input parameters)

your code works only because you have one QLineEdit.
But if you'll have more than one, your code wont work anymore, since all QLineEdits will have the same class name.

Its hard to say why your code gets int to an endless loop, from the code you posted.
It seems that you have a design problem.

P.S
Please post code in code tags, its hard to read it they way you posted it.

In addition, why do you use such an ansafe and complicated code?
Use QString instead of char*.
Then you can use opertator '==' insteader of memcmp().

madhukiranmp
8th November 2010, 04:20
sorry for the late reply.

Here is the code which didn't work.


bool TME_COM::eventFilter(QObject* call_object, QEvent* pevent)
{
QLineEdit *isQLineEdit = static_cast<QLineEdit*>(call_object);
if(call_object != isQLineEdit)
return false;
if(pevent->type() == QEvent::FocusIn)
{
virtualkeyboard->show();
}
return true;
}
else
{
virtualkeyboard->hide();
return false;
}

you are right, our design is having more QLineEdits. Out of 12 screens in our project 3 screens are having line edits. I want to show the VKB for these 3 screens.
I'm totally confused that how to show the virtual keyboard when clicked on line edit:(. Please give me a function, which I can use to show virtual keyboard for the line edits.

Additional Info about the project:
1. We have navigator menu, which has the push buttons linked to all other screens. i.e., when clicked on push button on the screen respective screen opens.
2. The navigator menu inherits QWidget class, the 3 screens where I want to show the VKB are non modal dialogs,which inherits QDialog class.

As I told earlier if I include the slot setWidgets program is entering infinite loop. Is there any alternate function or slot for setWidgets slot so that I can try.

high_flyer
8th November 2010, 09:07
This part of the code:


QLineEdit *isQLineEdit = static_cast<QLineEdit*>(call_object);
if(call_object != isQLineEdit)
return false;


makes no sense.
You are getting an address and then ask if the address you got is the address you got,and of course they are the same!
You have to check not the address against it self, but against the address of the QLineEdit you want to check!
That line edit is defined somewhere in your application probably in a ui file (if you use them).
Have a look at the post I posted where I suggested to you to do that and you will see my remark:
"where pLineEdit is the pointer to the clicked line edit."

madhukiranmp
8th November 2010, 09:53
bool TME_COM::eventFilter(QObject* call_object, QEvent* pevent)
{
QLineEdit *isQLineEdit = dynamic_cast<QLineEdit*>(call_object);

if(call_object != ui->TME_COM_ETHER1_IP1_TXTED) return false;
if(isQLineEdit)
{
if (pevent->type() == QEvent::FocusIn)
{
virtualkeyboard->show();
}
return true;
}
else
{
virtualkeyboard->hide();
return false;
}
}

This is the code part that I tried with your suggestion, TME_COM_ETHER1_IP1_TXTED is the pointer to the line edit for which I want to show the VKB. But It dint work:(
One more thing there are more than one line edits in this screen, I want to display the VKB for each line edit.

high_flyer
8th November 2010, 10:37
You don't need the check "if(isQLineEdit) since 'isQLineEdit' gets the address from 'call_object', and from the top of my head I think 'call_object' will never be NULL, since if no object sent and event no event is sent - which mean 'call_object' should never be NULL.
If at all you should check 'call_object != NULL', since you use it before you use 'isQLineEdit'.
That was a side note.

Now your code looks better, and it looks it should do what you want.
You didn't explain what you mean by "not working".
That can mean all kinds of things.
Put a break point , step through, and have a look which part of the code is not doing what you expect - you might see then also why.
Did you call installEventFilter() for the QLineEdits for which you want to catch the focus in event?


One more thing there are more than one line edits in this screen, I want to display the VKB for each line edit.
Just repeat the code for the line edit you have now for each of the line edits you want to have the VKB.

madhukiranmp
8th November 2010, 11:22
bool TME_COM::eventFilter(QObject* call_object, QEvent* pevent)
{
QLineEdit *isQLineEdit = static_cast<QLineEdit*>(call_object);

if(call_object != ui->TME_COM_ETHER1_IP1_TXTED) return false;
qDebug("Entering if\n");
if (pevent->type() == QEvent::FocusIn)
{
qDebug("entering show\n");
virtualkeyboard->show();
return true;
}
else
{
qDebug("entering hide\n");
virtualkeyboard->hide();
return false;
}
}

Yes, Of-course I've called installEventFilter() for the line edits.
"Not working" I mean if I click on line edit VKB is not displaying.
So as you told I put some Debug statements and tried, actually when I open the screen itself it's entering this event filter function. The program is not waiting till I click on lline edit. As soon as I open the TME_COM screen it's entering the event filter function. But I don't want that, whenever I click on line edit it should enter the event filter function.

In the output It's printing following Debug statements

Entering if
Entering hide
Entering if
Entering hide

and I'm getting one warning," unused variable isQlineEdit". What should I do to display the VKB for click on line edit?

high_flyer
8th November 2010, 11:48
The program is not waiting till I click on lline edit. As soon as I open the TME_COM screen it's entering the event filter function. But I don't want that, whenever I click on line edit it should enter the event filter function.
That is a correct behaviour.
An event filter gets all the events for the filtered widget.
In the function it self, as you are doing, you should filter out the event you want to handle.
So that is ok.

The warning you get tells you what the problem is - you have defined 'isQlineEdit' but you don't use it.
Just delete that line and the warning will go away.

Try 'QEvent::EnterEditFocus' instead of 'QEvent::FocusIn'


Yes, Of-course I've called installEventFilter() for the line edits.
Well, nothing is 'of course' when you try to debug code you can't see ;)

madhukiranmp
8th November 2010, 12:13
I tried with 'QEvent::EnterEditFocus', with this also VKB is not displaying, actually it's saying "EnterEditfocus is not a member of QEvent ".
Is there any function other than eventFilter(), so that I can use here. Because, I don't want to show the keyboard as soon as the screen opens. Instead, I want to display the VKB only when clicked on line edit.

:(

high_flyer
8th November 2010, 12:58
"EnterEditfocus is not a member of QEvent ".
It should be EnterEditFocus, with a 'F'.

In such cases check the QEvent documentation.


s there any function other than eventFilter(), so that I can use here.
You can subclass QLineEdit and overload focusInEvent().
But then your QLineEdit will have to get a pointer to the VKB, or otherwise have access to it.

Don't expect to be fed everything with a spoon - read the docs!
Look for answers in the docs!

madhukiranmp
8th November 2010, 13:13
Okay, I'll try with that. Thank you.

madhukiranmp
9th November 2010, 12:05
Hi. I got it worked with following, using signals and slots:)



connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(setWidgets(QWidget*, QWidget*)));

void TME_COM::setWidgets(QWidget *old, QWidget *newwid)
{
const char* ab;
if(newwid != 0)
{
ab = newwid->metaObject()->className();
if(strcmp(ab,"QLineEdit")==0)
{
virtualKeyBoard->show();
}
}

else
{
virtualKeyBoard->hide();
}
}

Thanks for your replies.
I've got one more issue.
The screens in our project resizes when double clicked on title bar. I want to disable this resize option.
so the questions are,
1. How to disable the resize of the screens or widget on double click of the title bar?
2. How to disable the context menu display, when right clciked on title bar?

high_flyer
9th November 2010, 13:12
Hi. I got it worked with following, using signals and slots
I was not aware the trolls added a signal for that, its hard to keep up with all the new features! (All though I see its a 4.1 feature (but I didn't need it))
Well, I learned something new too!:)

1. How to disable the resize of the screens or widget on double click of the title bar?
I don't know if Qt has something "ready" to be used for that.
You might need to catch the resize event for the window and re implement it.

2. How to disable the context menu display, when right clciked on title bar?
See WindowFlags.

madhukiranmp
30th December 2010, 08:47
Hi all,
I have created a simple application with a single combo box and some push buttons. This is to implement multilingual feature of Qt. I want to dynamically update the combo box if any new .qm file is added to the project folder. I'm getting the file name added to the combo box. But once I select the dynamically added item in the combo box the language changes and the corresponding new item disappears. I want it to be added permanently. please help how to do this.
Thanks in advance.

here is the code I've used

#include "detect.h"
#include "ui_detect.h"
#include "QFileSystemWatcher"
#include "QFileInfo"
#include "QTranslator"
#include "QTextStream"
#include "QString"
#include "QComboBox"

QTranslator langTranslator;
QString line1;
detect::detect(QWidget *parent) :
QDialog(parent),
ui(new Ui::detect)
{
ui->setupUi(this);
qApp->installTranslator(&langTranslator);
system("ls ..\ >new.txt");
system("comm -13 old.txt new.txt >difference.txt");
readdifference();

}

detect::~detect()
{
delete ui;
}

void detect::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
switch (e->type()) {
case QEvent::LanguageChange:
ui->retranslateUi(this);
break;
default:
break;
}
}

void detect::on_comboBox_activated(const QString & text)
{
if(text == tr("French"))
{
langTranslator.load("arrowpad_fr","C:/Documents and Settings/20010833/Desktop/testdet" );
}
else if(text == line1)
{
langTranslator.load(line1,"C:/Documents and Settings/20010833/Desktop/testdet" );
}

}
void detect::readdifference()
{
QString path="C:/Documents and Settings/20010833/Desktop/testdet";
QFile nfile("difference.txt");

if(!nfile.open(QIODevice::ReadOnly ))
return;
QTextStream in(& nfile);
while(!in.atEnd())
{
line1=in.readLine();
if(line1.endsWith("qm"))
{

ui->comboBox->addItem(line1,QVariant::Char);
// break;
}
}
}