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


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

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

场景1:

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

场景2:

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

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

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

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

至于QLineEdit而不是QLabel - 我去了QLineEdit因为我注意到我无法用QLabel从QLabel中选择文本进行复制。使用QLineEdit是可能的。


4700
2017-07-20 13:53


起源

只是想让你知道你的问题并没有被忽视......过去一天我一直在思考这个问题,但我想不出一个简单的方法来做你所要求的。根本不是您正在使用的项目是为什么设计的。它们是入门小部件,旨在允许输入更多数据,而不是可以轻松放入屏幕。如果您真的想要调整当前项目的大小,请尝试在布局中扩展QLabel。 - Caleb Huitt - cjhuitt


答案:


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

通常,你只需要打电话 QWidget::updateGeometry() 当。。。的时候 sizeHint() 可能已经改变了,就像你需要打电话一样 QWidget::update() 当内容可能已经改变。

然而,你的问题是 sizeHint() 添加文本时不会更改 QLineEdit 和 QTextEdit。有一个原因:人们不希望他们的对话框成长为他们类型:)

也就是说,如果您真的希望在这些小部件中按类型增长,则需要从它们继承并重新实现 sizeHint() 和 minimumSizeHint() 返回更大的尺寸,并可能 setText()append() 等来打电话 updateGeometry() 所以注意到sizehint的变化。

sizehint计算不会完全无关紧要,并且会更容易 QLineEdit 而不是 QTextEdit (这是秘密的 QAbstractScrollArea),但你可以看看 sizeHint() 和 minimumSizeHint() 灵感的实现(也是一个 QComboBox,它有一个完全按照你想要的模式: QComboBox::AdjustToContents

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


8
2017-07-22 16:08



QLabel对我不起作用的原因是自动换行。它拒绝分开一个单词,这在显示链接时是不可接受的。 - chacham15
我有同样的问题,需要QLabel真正支持WrapAtWordBoundaryOrAnywhere。 - Neil Wightman


对于QTextBrowser案例,您应该能够使用文档大小

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

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


2
2017-07-27 13:49





也许看一看 Python QT自动小部件调整器。它是用python编写的,但它可能会给你一些关于如何去做你需要的想法。


2
2017-12-15 19:05





我使用以下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 )


1
2017-11-29 23:39





好的工具 sizeHint() 方法。每次你的内容改变大小调用 updateGeometry() 内容更改时不改变大小使用 update()。 (updateGeometry() 自动呼叫 update())。


0
2017-11-28 19:18