12

当 qt4 小部件的内容发生变化时,它们的大小出现了一些问题。

我将用两个简单的场景来说明我的问题:

场景一:

我有一个 QLineEdit 小部件。有时,当我使用 QLineEdit.setText() 更改其内容时,单行字符串不再适合当前大小的小部件。我必须选择小部件并使用箭头键在两个方向滚动字符串才能看到所有内容。

场景二:

我有一个 QTextEdit 小部件。有时,当我使用 QTextEdit.setHtml() 更改其内容时,呈现的 HTML 内容不再适合当前大小的小部件。小部件开始显示水平和/或垂直滚动​​条,我可以使用它们滚动 HTML 内容。

在这种情况下,我想要的是有一些逻辑来决定是否在内容更改后,新内容将不再适合小部件并自动增加小部件的大小,以便一切都适合。

这些场景是如何处理的?我正在使用 PyQt4。

编辑:在阅读了评论和第一个答案(其中提到在小部件中输入内容)之后,我再次讨论了这个问题。发现一个可怕的错字,我感到非常惊讶。当我写 QTextEdit 时,我的意思是 QTextBrowser,我很抱歉误导了你。那就是:我有一个小部件,它呈现我正在更改的 HTML 代码,我希望小部件增长到足以显示所有内容而没有滚动条。

至于 QLineEdit 而不是 QLabel - 我选择了 QLineEdit,因为我注意到我无法用鼠标从 QLabel 中选择文本来复制它。使用 QLineEdit 是可能的。

4

5 回答 5

8

我在这里用 C++ 回答,因为这是我最熟悉的,而且您的问题并非特定于 PyQt。

通常,您只需要QWidget::updateGeometry()sizeHint()可能发生更改时调用,就像您需要QWidget::update()在内容可能更改时调用一样。

但是,您的问题是,将文本添加到andsizeHint()时不会改变。有一个原因:人们不希望他们的对话随着他们的类型而增长:)QLineEditQTextEdit

也就是说,如果您真的希望在这些小部件中随键入而增长行为,您需要从它们继承并重新实现sizeHint()minimumSizeHint()返回更大的尺寸,并可能setText()append()调用updateGeometry(),以便注意到 sizehint 的变化。

sizehint 计算不会完全微不足道,并且会QLineEdit比 for更容易QTextEdit(这是秘密 a QAbstractScrollArea),但您可以查看sizeHint()andminimumSizeHint()实现以获取灵感(也是 for QComboBox,它有一种模式可以完全按照您的意愿行事想要:QComboBox::AdjustToContents

编辑:您的两个用例(QTextBrowser w/o scrollbars 和 QLineEdit 而不是 QLabel 只是用于选择其中的文本)可以通过使用 QLabel 和最近的 Qt 来解决。QLabel 在 Qt 4.2 中获得了链接点击通知和所谓的“文本交互标志”(其中之一是 TextSelectableByMouse)。我能够弄清楚的唯一区别是加载新内容不是自动的,没有历史记录,并且在 QLabel 中没有微焦点提示(即从链接到链接的标签)。

于 2009-07-22T16:08:31.187 回答
2

For the QTextBrowser case you should be able to get the size of the document using

QTextBrowser::document()->size();

after setting the html, and then resizing it the QTextBrowser afterwards.

于 2009-07-27T13:49:41.863 回答
1

我通过使用以下 C++ 类实现了类似的效果:

文本编辑.h

#ifndef TEXTEDIT_H
#define TEXTEDIT_H

#include <QTextEdit>

class TextEdit : public QTextEdit
{
  Q_DISABLE_COPY( TextEdit )

public:
  TextEdit( QWidget* parent = NULL );
  TextEdit( const QString& text, QWidget* parent = NULL );
  virtual ~TextEdit();

  void fitToDocument( Qt::Orientations orientations );
  virtual QSize sizeHint() const;

private:
  int fittedHeight_;
  Qt::Orientations fittedOrientations_;
  int fittedWidth_;
};

#include "textedit-inl.h"

#endif // TEXTEDIT_H

文本编辑-inl.h

#ifndef TEXTEDITINL_H
#define TEXTEDITINL_H

#include "textedit.h"

inline TextEdit::TextEdit( QWidget* parent ) :
    QTextEdit( parent ), fittedOrientations_( 0 )
{ }

inline TextEdit::TextEdit( const QString& text, QWidget* parent ) :
    QTextEdit( text, parent ), fittedOrientations_( 0 )
{ }

inline TextEdit::~TextEdit()
{ }

inline QSize TextEdit::sizeHint() const
{
  QSize sizeHint = QTextEdit::sizeHint();
  if( fittedOrientations_ & Qt::Horizontal )
    sizeHint.setWidth( fittedWidth_ );
  if( fittedOrientations_ & Qt::Vertical )
    sizeHint.setHeight( fittedHeight_ );
  return sizeHint;
}

#endif // TEXTEDITINL_H

文本编辑.cpp

#include "textedit.h"

void TextEdit::fitToDocument( Qt::Orientations orientations )
{
  QSize documentSize( document()->size().toSize() );
  QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
  if( orientations & Qt::Horizontal ) {
    fittedWidth_ = documentSize.width() + (width() - viewport()->width());
    sizePolicy.setHorizontalPolicy( QSizePolicy::Fixed );
  }
  if( orientations & Qt::Vertical ) {
    fittedHeight_ = documentSize.height() + (width() - viewport()->width());
    sizePolicy.setVerticalPolicy( QSizePolicy::Fixed );
  }
  fittedOrientations_ = orientations;
  setSizePolicy( sizePolicy );
  updateGeometry();
}

例如,调用TextEdit::fitToDocument( Qt::Horizontal )会将小部件的宽度设置为一个固定宽度,该宽度正好足够大以适应文档及其周围环境(例如,垂直滚动条,如果有的话)。如果您的目标是在内容更改时发生这种情况,请将QTextEdit::textChanged()信号连接到调用TextEdit::fitToDocument().

至于您的问题QLabel,解决方案很简单:调用QLabel::setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::TextSelectableByMouse ).

于 2009-11-29T23:39:50.967 回答
1

也许看看Python QT Automatic Widget Resizer。虽然它是用 python 编写的,但它可能会给你一些关于如何去做你需要做的事情的想法。

于 2010-12-15T19:05:33.910 回答
0

好的实现sizeHint()方法。并且每次你的内容改变大小时调用updateGeometry() 当内容改变而不改变大小时使用update()。(updateGeometry()自动调用update())。

于 2009-11-28T19:18:00.570 回答