PDA

View Full Version : Focus on a QWidget item in a QWidget



vycke
31st December 2007, 19:08
I can't believe no one has asked about this (or at least that I couldn't find it)... but let's see if someone can give me an answer :)

I have a QDialog with a QFrame on it (and a QDialogButtonBox, and a few other widgets). When I try to place a QWidget "in" the frame (setParent(frame)) and show it (note: under Windows I have to have a move(0,0) for the widget or else the widgets start sliding down and to the right until it hits a certain point, then resets), the widgets on the widget (i.e. a QLineEdit on the 'page') do not get the focus. I've tried page->setFocus() -- but that just allows the QDialogButtonBox to have the default button work (weird, but it doesn't work (under Linux) until I added the setFocus()). I've tried calling a function in the page to set the focus to the QLineEdit (m_name->setFocus())... still nothing.

Can anyone see an obvious solution? Or do I need to try to get a small compilable example to post first?

Thanks,

Vycke

marcel
31st December 2007, 20:59
Better post an example and I will answer the post by correcting it. It is easier that way.

jacek
1st January 2008, 00:21
I'm not sure if it's going to help with the focus problem, but it sounds like you forgot to add a layout for that frame.

vycke
3rd January 2008, 14:20
Ok. I replaced the QFrame with a QVBoxLayout & am doing an insertWidget(0, page) (instead of just making the QFrame the parent of the page) -- even with the page->setFocus() call, it won't show.

I'm trying to make a small example to test this, but any other possible hints while I try to trim it down would be nice :)

Vycke

jacek
3rd January 2008, 14:25
Maybe you set QWidget::focusPolicy to Qt::NoFocus somewhere?

vycke
3rd January 2008, 14:49
(You'll have to put this into an app... qtest.ui is just a dialog (named QTestDlg) w/a QVBoxLayout, qname.ui is a widget (named QNameDlg) w/a QLineEdit)

testdlg.hpp


#include "ui_qtest.hpp"

class CTestDlg : public QDialog, private Ui::QTestDlg
{
Q_OBJECT

public:
CTestDlg(QWidget* parent = 0);
~CTestDlg();

void addPage(QWidget* page);
};


testdlg.cpp


#include "testdlg.hpp"

CTestDlg::CTestDlg(QWidget* parent) : QDialog(parent)
{
this->setupUi(this);
}

CTestDlg::~CTestDlg()
{
}

void CTestDlg::addPage(QWidget* page)
{
if (page)
{
vboxLayout->insertWidget(0, page);
page->show();
page->setFocus(Qt::OtherFocusReason);
}
}


and calling the above with



CTestDlg* test = new CTestDlg(this);
CNameDlg* page = new CNameDlg();

test->addPage(page);
test->show();


[I hope this is enough to show what I have -- and will give some idea what I'm doing & why it isn't setting the focus on the QLineEdit]

Vycke

vycke
3rd January 2008, 14:59
Maybe you set QWidget::focusPolicy to Qt::NoFocus somewhere?

The widgets/dialog both had Qt::NoFocus set -- but changing both to Qt::StrongFocus didn't fix this.

jacek
3rd January 2008, 20:48
Please post a compilable example.

vycke
7th January 2008, 17:15
Ok.. Here's the code:

main.cpp


#include <QtGui/QApplication>

#include "dialog.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Dialog dialog;
CNameDlg test;
dialog.addPage(&test);
return dialog.exec();
}


dialog.cpp


#include <QtGui>

#include "dialog.h"

Dialog::Dialog()
{
this->setupUi(this);
}

void Dialog::addPage(QWidget* page)
{
if (page)
{
vboxLayout->insertWidget(0, page);
page->show();
page->setFocus(Qt::OtherFocusReason);
}
}

CNameDlg::CNameDlg(QWidget* parent) : QWidget(parent)
{
this->setupUi(this);
}


dialog.h


#ifndef DIALOG_H
#define DIALOG_H

#include <QtGui/QDialog>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

#include <QtGui/QApplication>

class Dialog : public QDialog
{
Q_OBJECT

public:
Dialog();
void addPage(QWidget* page);

private:
QWidget *verticalLayout;
QVBoxLayout *vboxLayout;
QLabel *label;

void setupUi(QDialog *Dialog)
{
if (Dialog->objectName().isEmpty())
Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(535, 302);
Dialog->setFocusPolicy(Qt::StrongFocus);
verticalLayout = new QWidget(Dialog);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
verticalLayout->setGeometry(QRect(10, 30, 511, 221));
vboxLayout = new QVBoxLayout(verticalLayout);
vboxLayout->setObjectName(QString::fromUtf8("vboxLayout"));
vboxLayout->setContentsMargins(0, 0, 0, 0);
label = new QLabel(Dialog);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(10, 10, 54, 18));

Dialog->setWindowTitle(QApplication::translate("Dialog", "Dialog", 0, QApplication::UnicodeUTF8));
label->setText(QApplication::translate("Dialog", "Test", 0, QApplication::UnicodeUTF8));
} // setupUi
};


class CNameDlg : public QWidget
{
Q_OBJECT

public:
CNameDlg(QWidget *parent = 0);
QLabel *label;
QLineEdit *m_name;

void setupUi(QWidget *CNameDlg)
{
if (CNameDlg->objectName().isEmpty())
CNameDlg->setObjectName(QString::fromUtf8("CNameDlg"));
CNameDlg->resize(410, 111);
CNameDlg->setFocusPolicy(Qt::StrongFocus);
label = new QLabel(CNameDlg);
label->setObjectName(QString::fromUtf8("label"));
label->setGeometry(QRect(10, 10, 250, 18));
m_name = new QLineEdit(CNameDlg);
m_name->setObjectName(QString::fromUtf8("m_name"));
m_name->setGeometry(QRect(10, 60, 240, 27));
} // setupUi
};

#endif


and finally focus.pro


HEADERS = dialog.h
SOURCES = dialog.cpp \
main.cpp

# install
target.path = .
sources.files = $$SOURCES $$HEADERS *.pro
sources.path = .
INSTALLS += target sources


Note that some of the code was copied from the compile of the .ui files I have.

If you compile & run this, you'll have a dialog, with a label ("test") and an QLineEdit. The QLineEdit is +not+ the focus.

Vycke

jacek
7th January 2008, 19:59
It seems that the problem is caused by "page->setFocus(Qt::OtherFocusReason);" line --- comment it out and it should work. Other solution is make invoke setFocusProxy( m_name ) in CNameDlg.

vycke
7th January 2008, 21:00
It seems that the problem is caused by "page->setFocus(Qt::OtherFocusReason);" line --- comment it out and it should work. Other solution is make invoke setFocusProxy( m_name ) in CNameDlg.
Removing the setFocus() call didn't work (4.3.2... might be a bug there). But adding the setFocusProxy() in the contructor of CNameDlg did.

Thanks so much.

Vycke