PDA

View Full Version : Qt with Florence Virtual Keyboard



JonnyJP
15th December 2011, 15:41
Hi,
I'm working under Linux with Qt and the Florence virtual keyboard (http://florence.sourceforge.net/english.html). We need the keyboard to slide in and out whenever an input control (i.e. QLineEdit) receives focus. If I use Florence independently then apart from not being able to use Qt's easing curves to slide the keyboard, it doesn't work at all. According to the documentation this is due to the at-spi whatever that is.

I've managed to embed this into a QX11EmbedContainer but this still doesn't work as the widget grabs the focus away from my app.

Keyboard::Keyboard(int width, int height, QWidget *parent) :
QX11EmbedContainer(parent)
{
m_size.setWidth(width);
m_size.setHeight(height);

this->window()->setFocusPolicy(Qt::NoFocus);

setEnabled(false);

setFocusPolicy(Qt::NoFocus);

killFlorence();
}

Keyboard::~Keyboard()
{

}

// Kill all florence processes first
void Keyboard::killFlorence()
{
m_killFlorence = new QProcess(this);
QString killExec("pkill florence");

connect(m_killFlorence, SIGNAL(finished(int)), this, SLOT(startFlorence(int)));
m_killFlorence->start(killExec);
}

// Once pkill has finished, start Florence
void Keyboard::startFlorence(int exitStatus)
{
m_florence = new QProcess(this);
QString florenceExec("florence --use-config=/home/florence.conf"); // You don't actually need to run it

connect(m_florence, SIGNAL(started()), this, SLOT(queryWindowManger()));
m_florence->start(florenceExec);
}

// Once Florence has started, use wmctrl to get the window id
void Keyboard::queryWindowManger()
{
m_winInfo = new QProcess(this);

QString winInfoExec("wmctrl -l");

connect(m_winInfo, SIGNAL(readyReadStandardOutput()), this, SLOT(createFlorenceWidget()));

m_winInfo->start(winInfoExec);
}

// Strip out a lot of chars from the output of wmctrl to get the window id then embed the process into and show the QX11EmbedContainer.
void Keyboard::createFlorenceWidget()
{
QByteArray newData = m_winInfo->readAllStandardOutput();

QString text = QString::fromLocal8Bit(newData);

int pos = pos = text.indexOf("florence");

if (pos == -1)
{
queryWindowManger();
return;
}

pos -= 24;

text = text.left(pos);
text = text.right(10);

ulong id = text.toULong(0, 16);

Qt::WindowFlags flags;
flags = /*Qt::FramelessWindowHint | */Qt::WindowStaysOnTopHint;
setWindowFlags(flags);

setFocusPolicy(Qt::NoFocus);
embedClient(id);
show();

resize(m_size);
}

The reason we are using Florence is because the keyboard needs to support multiple languages, which it does. We couldn't find any other solution.

Also, unfortunately due to a poor design choice, parts of our UI are in QML so that also needs to be considered. The main focus is getting the data from Florence into the current Qt controls.

Does anyone have any ideas? Any help is greatly appreciated.

François Agrech
16th December 2011, 10:04
Hello JonnyJP,

I am the author of the Florence Virtual Keyboard. I have made a Qt version of Florence but it's not yet released to the public. There are some limits but it may suit your needs. It is optimized for touch screens (single touch, no multi-touch yet) and does not work well with the mouse as is.
Can you please tell me more about your project? Is it intended to be used with a touch screen? You can send me an email if you want and I can share the Qt widget with you. You can find my email address on Florence's web site.

If the Qt widget is not suitable for your project, I can still help you with at-spi but there are some other limits. You will need to use at-spi2 (which is at-spi over dbus) and http://gitorious.org/qt-at-spi/qt-at-spi, which was not very stable last time I tried it. It may be in better shape now.

If you sill want to go the route of QX11EmbedContainer, you need to use a focus proxy (see QWidget::setFocusProxy())

JonnyJP
16th December 2011, 10:50
Hi,
Many thanks for your prompt reply. The Qt Widget sounds like it will be just what we need so I'll send you an email soon.

I was actually looking at the focus proxy though I'm not sure how it will work with the QML side of things. Will I still need to use at-spi though?

JonnyJP
16th December 2011, 13:11
One further question not directly related to Florence...

When I call embedClient(id), I know the client is embedded as it sits in the window. However, the clientIsEmbedded signal isn't emitted and calling discardClient does nothing.

Any ideas?

James R. Matey
11th June 2012, 02:37
Dear Sir,

I came across this exchange on QT Centre. I also need a reliable QT virtual keyboard widget that I can use with Windows and Embedded Linux (ARM) targets. If there is a version of Florence available that might suit the bill, I am interested. The embedded target has only a touch screen for input.

Thanks in advance for any advice/assistance.

Best regards,

James R. Matey
jrmatey at
Ieee dot
org


Hello JonnyJP,

I am the author of the Florence Virtual Keyboard. I have made a Qt version of Florence but it's not yet released to the public. There are some limits but it may suit your needs. It is optimized for touch screens (single touch, no multi-touch yet) and does not work well with the mouse as is.
Can you please tell me more about your project? Is it intended to be used with a touch screen? You can send me an email if you want and I can share the Qt widget with you. You can find my email address on Florence's web site.

If the Qt widget is not suitable for your project, I can still help you with at-spi but there are some other limits. You will need to use at-spi2 (which is at-spi over dbus) and http://gitorious.org/qt-at-spi/qt-at-spi, which was not very stable last time I tried it. It may be in better shape now.

If you sill want to go the route of QX11EmbedContainer, you need to use a focus proxy (see QWidget::setFocusProxy())

ChrisW67
11th June 2012, 08:28
You could email the author directly. See the mailto link at the bottom of the project page (http://florence.sourceforge.net/english.html)