PyQt:如何在内容更改时处理窗口小部件的自动调整大小

时间:2009-07-20 13:53:55

标签: c++ python qt qt4 pyqt4

当内容发生变化时,我遇到了qt4小部件大小的问题。

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

情景1:

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

情景2:

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

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

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

编辑:在阅读了评论和第一个答案(提到在窗口小部件中输入内容)之后,我再次回答了这个问题。发现一个可怕的拼写错误令我不高兴。当我写QTextEdit时,我的意思是QTextBrowser,我为误导你而道歉。那就是:我有一个小部件,它呈现我正在改变的HTML代码,我希望小部件增长到足以显示所有内容而不需要滚动条。

至于QLineEdit而不是QLabel - 我去了QLineEdit因为我注意到我不能用QLabel选择文本来复制它。使用QLineEdit是可能的。

5 个答案:

答案 0 :(得分:8)

我在这里用C ++回答,因为这是我最熟悉的,而你的问题并不是PyQt所特有的。

通常情况下,您只需在QWidget::updateGeometry()可能已更改时致电sizeHint(),就像您需要在内容可能已更改时调用QWidget::update()一样。

但是,您的问题是sizeHint()在将文字添加到QLineEditQTextEdit时不会发生变化。出于某种原因:人们不希望他们的对话框成长为他们类型:)

也就是说,如果您真的希望在这些小部件中按类型增长,则需要从这些小部件继承并重新实现sizeHint()minimumSizeHint()以返回更大的大小,并且可能setText() 1}},append()等来调用updateGeometry(),以便注意到sizehint更改。

sizehint计算不会完全无关紧要,QLineEditQTextEdit(秘密地为QAbstractScrollArea)更容易,但你可以查看{灵感的{1}}和sizeHint()实现(也是minimumSizeHint()的实现,具有完全符合您要求的模式:QComboBox

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

答案 1 :(得分:2)

对于QTextBrowser案例,您应该能够使用

获取文档的大小
QTextBrowser::document()->size();

设置html后,然后调整QTextBrowser的大小。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

textedit.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

textedit.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 )

答案 4 :(得分:0)

确定实施sizeHint()方法。每当您的内容更改大小时,请致电updateGeometry() 如果内容更改而不更改大小,请使用update()。 (updateGeometry()会自动拨打update())。