PDA

View Full Version : heightforWidth



vermarajeev
11th September 2007, 09:26
Hi All,
How to get the heightForWidth for a widget. I always get the value as -1. Is there anything I'm missing?

The following is my code.


TextEdit::TextEdit(QWidget *parent)
:QTextEdit(parent)
{
setGeometry( geometry().x(), geometry().y(), parent->width(), 20 );
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOf f);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff) ;

QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding);
sizePolicy.setHeightForWidth(true);
setSizePolicy(sizePolicy);
connect( this, SIGNAL( textChanged() ), this, SLOT( slotTextChanged() ) );
setMouseTracking( true );
}
TextEdit::~TextEdit()
{}

void TextEdit::slotTextChanged()
{
qDebug() << heightForWidth ( width() );
}


int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget widget;
widget.resize( 400, 20 );
TextEdit* textEdit = new TextEdit( &widget );
widget.show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
return a.exec();
}

Thanks in advance.

wysota
11th September 2007, 10:33
Did you implement heightForWidth() method for your widget? You get -1 because that's what the default implementation returns.

vermarajeev
11th September 2007, 11:44
Did you implement heightForWidth() method for your widget? You get -1 because that's what the default implementation returns.

I had used QTextEdit::heightForWidth() in Qt3. I cannot find an alternative in Qt4.

BTW: If I have to implement my own heightForWidth() then I dont see any reasons Trolls defining it for us.

wysota
11th September 2007, 12:05
I had used QTextEdit::heightForWidth() in Qt3. I cannot find an alternative in Qt4.


int QWidget::heightForWidth ( int w ) const [virtual]
Returns the preferred height for this widget, given the width w.
If this widget has a layout, the default implementation returns the layout's preferred height. if there is no layout, the default implementation returns -1 indicating that the preferred height does not depend on the width.


BTW: If I have to implement my own heightForWidth() then I dont see any reasons Trolls defining it for us.
I'm afraid I don't understand.

vermarajeev
11th September 2007, 12:32
I'm afraid I don't understand.

What I meant is, Do I really need to implement heightForWidth() in QTextEdit. If I have to do so then why do Trolls define QWidget::heightForWidth()?
I'm looking for some built in function provided by Qt4 rather than writting my own functionality.



f this widget has a layout, the default implementation returns the layout's preferred height. if there is no layout, the default implementation returns -1 indicating that the preferred height does not depend on the width.
Though I defined a layout for my widget in the above sample, why I always get the value as -1?

Can you please correct the sample that I wrote, above.

Thanks

wysota
11th September 2007, 12:46
What I meant is, Do I really need to implement heightForWidth() in QTextEdit.
Depends what you want to achieve.


If I have to do so then why do Trolls define QWidget::heightForWidth()?
So that you can use the "heightForWidth" feature... I seem still not to understand your question. Do you know what heightForWidth is for?


Though I defined a layout for my widget in the above sample, why I always get the value as -1?
You defined a layout for QTextEdit? heightForWidth returns the size of the layout of the widget, not of the widget's parent.

vermarajeev
11th September 2007, 12:59
I want to resize the QTextEdit so I don't get a vertical scroll bar, based on the
height of the formatted text. I had used QTextEdit::heightForWidth() in Qt3. The following code was written in Qt3. I want to implement the same in Qt4. Can you please help?


void TextEdit::slotTextChanged()
{
int height = heightForWidth(width());
resize(width(), height);
}


The slotTextChanged() is connected as follows:

connect(this, SIGNAL(textChanged()), this, SLOT( slotTextChanged()));

wysota
11th September 2007, 13:08
QTextEdit *te = new ...;
//...
QTextDocument *d = te->document();
QSize docSize = d->size();
int l, t, r, b;
te->getContentsMargins(&l, &t, &r, &b);
docSize+=QSize(l+r, t+b);
docSize+=QSize(10,10); // just in case ;)
te->resize(docSize);
Something like that should do the trick. heightForWidth is for something completely different - it tells the layout that the widget can sacrifice some of its width exchanging that for an additional height (like a label with wordwrapping turned on).

dimuz
11th September 2007, 13:35
wysota, nice solution :)

How about arbitrary widget which defines hasHeightForWidth()?
For example word wrapped QLabel?
Do you know any solution in this case? I'd greatly appressiate.
I experience a whole lot of problems if I have word-wrapped QLabel in my layout. (like all size policies being ignored)

veda
11th September 2007, 14:02
Hello guys,,

In what scenario the heightForWidth will return some valid value..

Even after setting the layout,SizePolicies....

heightForWidth function always return -1.

wysota
11th September 2007, 14:07
wysota, nice solution :)

How about arbitrary widget which defines hasHeightForWidth()?
For example word wrapped QLabel?
Do you know any solution in this case? I'd greatly appressiate.
I experience a whole lot of problems if I have word-wrapped QLabel in my layout. (like all size policies being ignored)

Take a look at the source code of QLabelPrivate::sizeForWidth. It is the place where the preferred height of the label is calculated. As you can see QLabel uses a QTextDocument behind the scenes (through QTextControl), so you can use the exact same approach with QLabel as with QTextEdit.

Using QTextDocument::setTextWidth you can tell the document to calculate the size for this particular width and then query for the size using size().

But if your policies are ignored then it could mean your layout is messed up, as you shouldn't experience the effects you described with a word wrapping label.

wysota
11th September 2007, 14:18
Hello guys,,

In what scenario the heightForWidth will return some valid value..

Even after setting the layout,SizePolicies....

heightForWidth function always return -1.


#include <QtGui>
#include <QtCore>
#include <QtDebug>

class W : public QWidget {
public:
W(QWidget *p=0) : QWidget(p){
QSizePolicy poli(QSizePolicy::Expanding, QSizePolicy::MinimumExpanding);
poli.setHeightForWidth(true);
setSizePolicy(poli);
}
int heightForWidth(int w) const { return w; }
QSize sizeHint() const { return QSize(100,100); }
protected:
void paintEvent(QPaintEvent *pe){
QPainter p(this);
p.drawRect(rect().adjusted(0, 0, -1, -1));
}
};

int main(int argc, char **argv){
QApplication app(argc, argv);
QWidget w;
QVBoxLayout *l = new QVBoxLayout(&w);
for(int i=0;i<5;i++)
l->addWidget(new W);
w.show();
qDebug() << w.heightForWidth(w.width());
return app.exec();
}

dimuz
11th September 2007, 14:22
wysota
Thanks! Cool. I have seen sizeForWidth() but i gave it a fast look, not dwelling further - and i didn't noticed that it uses QTextEdit.

Thanks for the hint!

As for messed up layout - nope. it isn't messed up.
Even trolls aknowledged that this is a bug, but this is a wont fix for some reason I didn't fully understand.
To reproduce in designer - simply create widget with QVBoxLayout, put qlabel with some wordwrapped text (expanding on more than one line) and put qlineedit in this layout too. now press 'ctrl-r' and try to resize to minimum and you'll see the Truth (TM) ;)
Qt 4.3.1