Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt GUI _ QLineEdit, как сделать так, чтобы пока он пуст там появлялся текст?

Автор: entmobile 4.2.2009, 10:11

Вопрос по lineEdit: как узнать когда он в фокусе а когда нет? Пытался написать свое класс на основе QLineEdit и из focusEventов емитеть сигнал, нечего не получилось!:( Может есть более корректное решение? В итоге мне надо сделать следующее: если LineEdit пуст там появляется текст, при клике(табуляции) туда текст исчезает :)))

#include <QLineEdit>
#include <QFocusEvent>

class authEdit : public QLineEdit
{
Q_OBJECT
public:
    authEdit(QWidget *parent = 0);

signals:
    void onEnterEvent();
    void onLeaveEvent();


protected:
    bool enterFlag;
    void focusInEvent (QFocusEvent *event );
    void focusOutEvent ( QFocusEvent *event);
};


#include "authedit.h"

authEdit::authEdit(QWidget *parent)
        : QLineEdit (parent)
{
    enterFlag=false;
}

void authEdit::focusInEvent (QFocusEvent *event )
{
   if (!enterFlag) {
       emit onEnterEvent();
       enterFlag=true;
   }
}

void authEdit::focusOutEvent ( QFocusEvent *event)
{
    if (enterFlag) {
        emit onLeaveEvent();
        enterFlag=false;
    }
}

Автор: ViGOur 4.2.2009, 11:06

Я думаю лучше это делать в paintEvent, примерно так:

void CMyClass::paintEvent(QPaintEvent *)
{
    if( !pEdit->hasFocus() && pEdit->text().isEmpty())
    {
         QPainter painter( pEdit);
         painter.setPen(Qt::gray);
         painter.setFont(QFont("Arial", 12));
         painter.drawText(pEdit->rect(), Qt::AlignCenter, "Введите текст");
    }
}

Автор: Tonal 4.2.2009, 11:17

focusInEvent, focusOutEvent. Оно?

Автор: Litkevich Yuriy 4.2.2009, 11:40

entmobile, в обработчиках событий можно просто устанавливать/удалять текст:

void authEdit::focusInEvent (QFocusEvent *event )
{
    setText("");
}

void authEdit::focusOutEvent ( QFocusEvent *event)
{
    setText("Type here");
}

Автор: SABROG 4.2.2009, 11:41

Цитата(ViGOur @ 4.2.2009, 11:06) *
Я думаю лучше это делать в paintEvent, примерно так:

Отрисовка виджета в чужом paintEvent'e :o: ?

Только лучше не сбрасывать текст и не перезаписывать, если он пользовательский. А то обидется юзер, когда сообщение по аське придет :)

Автор: kuler 4.2.2009, 11:45

hasFocus не пробовал?

Автор: Litkevich Yuriy 4.2.2009, 11:53

Цитата(SABROG @ 4.2.2009, 14:41) *
Отрисовка виджета в чужом paintEvent'e
не виджета, а всего лиш текста нарисованого на виджете, ведь это подсказка типа "напишите ваше имя"

Автор: SABROG 4.2.2009, 11:59

Цитата(Litkevich Yuriy @ 4.2.2009, 11:53) *
Цитата(SABROG @ 4.2.2009, 14:41) *
Отрисовка виджета в чужом paintEvent'e
не виджета, а всего лиш текста нарисованого на виджете, ведь это подсказка типа "напишите ваше имя"

Да, но тут явная передача чужого виджета в painter. По идее на такое дебаг сообщение должно выводится или не работать совсем. А если просто поверх рисовать в главном окне, то это чревато тем, что при скрытом edit'е текст нарисуется где-нибудь на другом контроле, например при переключении tab'ов.

Автор: Litkevich Yuriy 4.2.2009, 12:18

Цитата(SABROG @ 4.2.2009, 14:59) *
то это чревато тем, что при скрытом edit'е текст нарисуется где-нибудь на другом контроле
ну програмист должен отдавать себе отчет в том, что он делает. Это лишь пример, и здается мне лучший из приведенных.

Автор: kuler 4.2.2009, 12:32

а почему focusInEvent, focusOutEvent не устроил?

Автор: ViGOur 4.2.2009, 13:13

Цитата(SABROG @ 4.2.2009, 11:41) *
Отрисовка виджета в чужом paintEvent'e :o: ?
Почему нет? Может я просто мало рисовал в Qt и чего-то не понимаю? (я и правда мало рисовал)

Чем хорошо именно рисование на виджете, так это тем, что мы не трогаем текст виджета. :)

Автор: entmobile 4.2.2009, 13:25

Цитата(SABROG @ 4.2.2009, 11:41) *
Чем хорошо именно рисование на виджете, так это тем, что мы не трогаем текст виджета. :)

В этом ты прав!!! Но если переписывать paintevent у lineedit то придеться полностью его перерисовывать: текст в нем и т.д. или есть вариант что бы дорисовать то что надо а остальное оставить? пока помог вариант с выводом текста в focusEvent`ах.

Автор: entmobile 4.2.2009, 14:02

Цитата(ViGOur @ 4.2.2009, 12:06) *
Я думаю лучше это делать в paintEvent


Вот немного поправил твой вариант!!! Спасибо огромное!!
CODE

void authEdit::paintEvent(QPaintEvent *event)
{
if (text().isEmpty() && !hasFocus() && !inactiveText.isEmpty()) { //можно и без hasFocus, так даже интереснее будет
QLineEdit::paintEvent(event);
QPainter painter(this);
painter.setPen(Qt::gray);
painter.setFont(QFont("Arial", 12));
painter.drawText(rect(), Qt::AlignCenter, inactiveText);
} else
QLineEdit::paintEvent(event);
}

P.S. authEdit это класс наследник от QLineEdit.

Автор: Litkevich Yuriy 4.2.2009, 14:32

Цитата(entmobile @ 4.2.2009, 17:02) *
Вот немного поправил твой вариант!!! Спасибо огромное!!
Эдик предлагал использовать событие перерисовки родительского виджета, и это более удачный вариант чем твой

С другой стороны, твой вариант хорош тем, что можно сделать наследника от QLineEdit намногие случаи жизни с таким поведением

entmobile, для твоего случая можно такую модернизацию провести:
        //painter.setFont(QFont("Arial", 12));
        painter.setFont(this->font());
дабы не было жестко зашитого в код размера шрифта

Автор: kuler 4.2.2009, 15:26

Цитата(entmobile @ 4.2.2009, 13:25) *
Но если переписывать paintevent у lineedit то придеться полностью его перерисовывать: текст в нем и т.д. или есть вариант что бы дорисовать то что надо а остальное оставить?

вызвать родительский метод

Автор: Litkevich Yuriy 4.2.2009, 15:30

kuler, он так и сделал

Автор: trdm 4.2.2009, 16:04

Цитата(Litkevich Yuriy @ 4.2.2009, 14:32) *
entmobile, для твоего случая можно такую модернизацию провести:
        //painter.setFont(QFont("Arial", 12));
        painter.setFont(this->font());
дабы не было жестко зашитого в код размера шрифта

а мне ихмается что это уже делает
QPainter painter(this);

Автор: Litkevich Yuriy 4.2.2009, 16:45

может быть, я с рисованием еще не работал. Так на удачу воткнул

Автор: Константин 16.2.2009, 2:38

всё это уже есть в http://www.prog.org.ru/topic_7795_0.html - в доп.компонентах на prog.org.ru
скоро будет свежая версия...

Автор: z0D5e8n7x 23.3.2010, 1:05

Цитата(Константин @ 16.2.2009, 2:38) *
всё это уже есть в http://www.prog.org.ru/topic_7795_0.html - в доп.компонентах на prog.org.ru
скоро будет свежая версия...


я тут сделал свой вариант попроще, мож кому сгодится
Раскрывающийся текст

#ifndef QWEBSTYLEEDIT_H
#define QWEBSTYLEEDIT_H

#include <QLineEdit>
#include <QColor>

class QWebStyleEdit : public QLineEdit
{
    Q_OBJECT
    Q_PROPERTY(QString grayedText READ grayedText WRITE setGrayedText)

    QString m_grText;
    QColor base,alternate;
    QColor text,brtext;
    bool modified;

    void setBackgroundColor(QColor);
    void setForegroundColor(QColor);
    void setItalic(bool);

public:
    QWebStyleEdit(QWidget * parent = 0, QString grText = QString());

    void setGrayedText(const QString &);
    QString grayedText() const;

    void setText(const QString &);
protected:
    void focusInEvent(QFocusEvent *);
    void focusOutEvent(QFocusEvent *e);
};

#endif // QWEBSTYLEEDIT_H


#include "qwebstyleedit.h"
#include <QPalette>

QWebStyleEdit::QWebStyleEdit(QWidget * parent,QString grText):QLineEdit(parent)
{
    setGrayedText(grText);
    base = palette().color(QPalette::Base);
    alternate = palette().color(QPalette::AlternateBase);
    text = palette().color(QPalette::Text);
    brtext = palette().color(QPalette::Midlight);
    setBackgroundColor(alternate);
    setForegroundColor(brtext);
    setItalic(true);
}

void QWebStyleEdit::setGrayedText(const QString &grText)
{
    m_grText=grText;
    if(QLineEdit::text().isEmpty())
        QLineEdit::setText(m_grText);
}

QString QWebStyleEdit::grayedText() const
{
    return m_grText;
}

void QWebStyleEdit::focusInEvent(QFocusEvent *e)
{
    QLineEdit::focusInEvent(e);
    setBackgroundColor(base);
    setForegroundColor(text);
    if(!modified)
        QLineEdit::setText("");
    setItalic(false);
}

void QWebStyleEdit::focusOutEvent(QFocusEvent *e)
{
    QLineEdit::focusOutEvent(e);
    setBackgroundColor(alternate);
    setForegroundColor(brtext);
    if(QLineEdit::text().isEmpty()){
        QLineEdit::setText(m_grText);
        modified = false;
        setItalic(true);
    } else {
        modified = true;
    }
}

void QWebStyleEdit::setBackgroundColor(QColor color)
{
    QPalette p = palette();
    p.setColor(QPalette::Base, color);
    setPalette(p);
}

void QWebStyleEdit::setForegroundColor(QColor color)
{
    QPalette p = palette();
    p.setColor(QPalette::Text, color);
    setPalette(p);
}

void QWebStyleEdit::setText(const QString &text)
{
    QLineEdit::setText(text);
    if(text.isEmpty())
        modified = false;
    else
        modified = true;
}

void QWebStyleEdit::setItalic(bool it)
{
    QFont fnt(font());
    fnt.setItalic(it);
    setFont(fnt);
}

Автор: z0D5e8n7x 23.3.2010, 3:49

а блин, куча косяков

Раскрывающийся текст

#ifndef QWEBSTYLEEDIT_H
#define QWEBSTYLEEDIT_H

#include <QLineEdit>
#include <QColor>

class QWebStyleEdit : public QLineEdit
{
    Q_OBJECT
    Q_PROPERTY(QString grayedText READ grayedText WRITE setGrayedText)

    QString m_grText;
    QColor base,alternate;
    QColor fgtext,bgtext;
    bool modified;

    void setBackgroundColor(QColor);
    void setForegroundColor(QColor);
    void setItalic(bool);

public:
    QWebStyleEdit(QWidget * parent = 0, QString grText = QString());

    void setGrayedText(const QString &);
    QString grayedText() const;

    void setText(const QString &);
    QString text () const;
protected:
    void focusInEvent(QFocusEvent *);
    void focusOutEvent(QFocusEvent *e);
};

#endif // QWEBSTYLEEDIT_H

#include "qwebstyleedit.h"
#include <QPalette>

QWebStyleEdit::QWebStyleEdit(QWidget * parent,QString grText):QLineEdit(parent)
{
    setGrayedText(grText);
    base = palette().color(QPalette::Base);
    alternate = palette().color(QPalette::AlternateBase);
    fgtext = palette().color(QPalette::Text);
    bgtext = palette().color(QPalette::Midlight);
    setBackgroundColor(alternate);
    setForegroundColor(bgtext);
    setItalic(true);
    modified = false;
}

void QWebStyleEdit::setGrayedText(const QString &grText)
{
    m_grText=grText;
    if(QLineEdit::text().isEmpty())
        QLineEdit::setText(m_grText);
}

QString QWebStyleEdit::grayedText() const
{
    return m_grText;
}

void QWebStyleEdit::focusInEvent(QFocusEvent *e)
{
    QLineEdit::focusInEvent(e);
    setBackgroundColor(base);
    setForegroundColor(fgtext);
    if(!modified)
        QLineEdit::setText("");
    setItalic(false);
}

void QWebStyleEdit::focusOutEvent(QFocusEvent *e)
{
    QLineEdit::focusOutEvent(e);
    setBackgroundColor(alternate);
    setForegroundColor(bgtext);
    if(QLineEdit::text().isEmpty()){
        QLineEdit::setText(m_grText);
        modified = false;
        setItalic(true);
    } else {
        modified = true;
    }
}

void QWebStyleEdit::setBackgroundColor(QColor color)
{
    QPalette p = palette();
    p.setColor(QPalette::Base, color);
    setPalette(p);
}

void QWebStyleEdit::setForegroundColor(QColor color)
{
    QPalette p = palette();
    p.setColor(QPalette::Text, color);
    setPalette(p);
}

void QWebStyleEdit::setText(const QString &text)
{
    QLineEdit::setText(text);
    if(text.isEmpty())
        modified = false;
    else
        modified = true;
}

QString QWebStyleEdit::text() const
{
    if(modified)
        return QLineEdit::text();
    else
        return QString("");
}

void QWebStyleEdit::setItalic(bool it)
{
    QFont fnt(font());
    fnt.setItalic(it);
    setFont(fnt);
}


Автор: novichkov 25.3.2010, 20:46

А можно просто подождать Qt 4.7 :D Там у QLineEdit есть property placeholderText. Этот код уже есть в исходных текстах SDK Qt 4.6 windows.

Автор: Sokoloff 26.3.2010, 13:17

Цитата(Litkevich Yuriy @ 4.2.2009, 14:32) *
Цитата(entmobile @ 4.2.2009, 17:02) *
Вот немного поправил твой вариант!!! Спасибо огромное!!
Эдик предлагал использовать событие перерисовки родительского виджета, и это более удачный вариант чем твой
А чем рисование в родителе лучше чем самообслуживающийся виджет?

Автор: Litkevich Yuriy 26.3.2010, 13:24

Цитата(Sokoloff @ 26.3.2010, 16:17) *
А чем рисование в родителе лучше чем самообслуживающийся виджет?
тем, что можно взять произвольный виджет, а не только QLineEdit

Автор: KuZ 26.3.2010, 19:02

Вот возможно так:

CODE
class LE : public QLineEdit
{
public:
LE(QWidget *wgt = 0);
protected:
virtual void focusInEvent(QFocusEvent *);
virtual void focusOutEvent(QFocusEvent *);
};

CODE
LE::LE(QWidget *wgt) : QLineEdit(wgt){}
void LE::focusInEvent(QFocusEvent *e)
{
QLineEdit::focusInEvent(e);
QPalette p = palette();
p.setColor(QPalette::Text,Qt::black);
setPalette(p);
setText(text() == "Enter Text" ? "" : text());
}
void LE::focusOutEvent(QFocusEvent *e)
{
QLineEdit::focusOutEvent(e);
QPalette p = palette();
p.setColor(QPalette::Text,Qt::gray);
setPalette(p);
setText(text().isEmpty() ? "Enter Text" : text());
}

только если набраный текст Enter Text, то "ошибка" чето придумать можно чтоб подобный вариант работал.

Автор: SABROG 27.3.2010, 3:46

В Qt 4.7 должен появится метод setPlaceholderText. В Qt 4.6 он уже реализован, но не доступен. Видимо тролли нас хотят удивить, ну или еще не все отладили. Метод работает, но достучаться можно только через хак:

#include "private/qlineedit_p.h"
...
namespace Hack { template <class To, class From> inline To* d_ptr(From* ptr){ return (To*)QObjectPrivate::get(ptr);}}
...
Hack::d_ptr<QLineEditPrivate>(ui->lineEdit)->placeholderText = "Test";

Автор: z0D5e8n7x 30.3.2010, 18:19

чет у меня все криво и косо ((

опять поправил - http://z0d5e8n7x.ru/blog/2010/03/24/qlineedit-v-stile-web/

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)