具有动态变化内容的 QScrollArea

2024-02-28

I have a QScrollArea with some buttons in it, like shown on the picture. enter image description here

布局的思路是: 1.左右按钮太宽时应使用滚动按钮

2.滚动区域按钮数量可动态改变 3. 应利用任何可用空间来尽可能扩大滚动区域。如果不存在这样的空间,则应使用导航按钮进行滚动。

With my current implementation when i increase the buttons i have this: enter image description here

But there is free space on the right, so this should look like: enter image description here

例如,如果我再次增加到 10,则应该出现滚动条(因为布局由小部件限制)。

我想知道除了手动调整小部件大小之外是否还有其他方法(因为 ui 可以翻译,按钮可以更改大小提示,而且真正的设计更复杂:(

这是我的 ScrollAreaTest 小部件的实现:

#include "MainWidget.h"

#include <QLineEdit>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
#include <QPushButton>
#include <QDebug>
#include "ButtonWidget.h"

#include "CheckableButtonGroup.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent),
      m_scrollArea( 0 ),
      m_lineEdit( 0 ),
      m_buttons( 0 )
{
    QVBoxLayout* mainLayout = new QVBoxLayout( this );
    QWidget* firstRow = new QWidget;
    QHBoxLayout* firstRowLayout = new QHBoxLayout( firstRow );

    QPushButton* left  = new QPushButton;
    QPushButton* right = new QPushButton;

    m_buttons = new CheckableButtonGroup( Qt::Horizontal );
    m_buttons->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
    m_buttons->setButtonsCount( 5 );
    m_buttons->setStyleSheet( "border: none" );

    QWidget* const buttonsContainer = new QWidget;
    QHBoxLayout* const buttonsContainerLayout = new QHBoxLayout( buttonsContainer );
    buttonsContainerLayout->setSpacing( 0 );
    buttonsContainerLayout->setSizeConstraint( QLayout::SetMinAndMaxSize );
    buttonsContainerLayout->setMargin( 0 );
    buttonsContainerLayout->addWidget( m_buttons, 0, Qt::AlignLeft );

    qDebug() << m_buttons->buttons()[ 0 ]->size();

    m_scrollArea = new QScrollArea;
    m_scrollArea->setContentsMargins( 0, 0, 0, 0 );
    m_scrollArea->setWidget( buttonsContainer );
    m_scrollArea->setWidgetResizable( true );
    m_scrollArea->setStyleSheet( "border: 1px solid blue" );
    m_scrollArea->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );

    firstRowLayout->addWidget( left        , 0, Qt::AlignLeft );
    firstRowLayout->addWidget( m_scrollArea, 1, Qt::AlignLeft );
    firstRowLayout->addWidget( right       , 0, Qt::AlignLeft );

    m_lineEdit = new QLineEdit;
    QPushButton* button = new QPushButton;
    QHBoxLayout* secondRowLayout = new QHBoxLayout;
    secondRowLayout->addWidget( m_lineEdit );
    secondRowLayout->addWidget( button );

    connect( button, SIGNAL(clicked()), SLOT(setButtonsCount()) );

    mainLayout->addWidget( firstRow, 1, Qt::AlignLeft );
    mainLayout->addLayout( secondRowLayout );

    button->setText( "Set buttons count" );

    buttonsContainer->resize( m_buttons->buttonsOptimalWidth(), buttonsContainer->height() );
    m_buttons->resize( m_buttons->buttonsOptimalWidth(), m_buttons->height() );

    //area->resize( 100, area->height() );
    //area->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
}

MainWidget::~MainWidget()
{
}

void MainWidget::setButtonsCount()
{
    m_buttons->setButtonsCount( m_lineEdit->text().toInt() );
}

这是包含问题的整个 Qt 项目:https://drive.google.com/file/d/0B-mc4aKkzWlxQzlPMEVuNVNKQjg/edit?usp=sharing https://drive.google.com/file/d/0B-mc4aKkzWlxQzlPMEVuNVNKQjg/edit?usp=sharing


基本步骤是:

  1. 包含按钮的容器小部件(您的CheckableButtonGroup)必须有一个QLayout::SetMinAndMaxSize尺寸约束集。然后它就足够大以容纳按钮。它的大小策略并不重要,因为您只需将其放入QScrollArea,而不是进入另一个布局。

  2. 滚动区域需要根据其所容纳的小部件的大小来设置其最大尺寸。默认实现不会执行此操作,因此必须通过监视嵌入式小部件的调整大小事件来实现它。

下面的代码是在 Qt 4.8 和 5.2 下运行的最小示例。

// https://github.com/KubaO/stackoverflown/tree/master/questions/scrollgrow-21253755
#include <QtGui>
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtWidgets>
#endif

class ButtonGroup : public QWidget {
   Q_OBJECT
   QHBoxLayout m_layout{this};
public:
   ButtonGroup(QWidget * parent = 0) : QWidget{parent} {
      m_layout.setSizeConstraint(QLayout::SetMinAndMaxSize); // <<< Essential
   }
   Q_SLOT void addButton() {
      auto n = m_layout.count();
      m_layout.addWidget(new QPushButton{QString{"Btn #%1"}.arg(n+1)});
   }
};

class AdjustingScrollArea : public QScrollArea {
   bool eventFilter(QObject * obj, QEvent * ev) {
      if (obj == widget() && ev->type() == QEvent::Resize) {
         // Essential vvv
         setMaximumWidth(width() - viewport()->width() + widget()->width());
      }
      return QScrollArea::eventFilter(obj, ev);
   }
public:
   AdjustingScrollArea(QWidget * parent = 0) : QScrollArea{parent} {}
   void setWidget(QWidget *w) {
      QScrollArea::setWidget(w);
      // It happens that QScrollArea already filters widget events,
      // but that's an implementation detail that we shouldn't rely on.
      w->installEventFilter(this);
   }
};

class Window : public QWidget {
   QGridLayout         m_layout{this};
   QLabel              m_left{">>"};
   AdjustingScrollArea m_area;
   QLabel              m_right{"<<"};
   QPushButton         m_add{"Add a widget"};
   ButtonGroup         m_group;
public:
   Window() {
      m_layout.addWidget(&m_left, 0, 0);
      m_left.setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred);
      m_left.setStyleSheet("border: 1px solid green");

      m_layout.addWidget(&m_area, 0, 1);
      m_area.setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
      m_area.setStyleSheet("QScrollArea { border: 1px solid blue }");
      m_area.setWidget(&m_group);
      m_layout.setColumnStretch(1, 1);

      m_layout.addWidget(&m_right, 0, 2);
      m_right.setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
      m_right.setStyleSheet("border: 1px solid green");

      m_layout.addWidget(&m_add, 1, 0, 1, 3);
      connect(&m_add, SIGNAL(clicked()), &m_group, SLOT(addButton()));
   }
};

int main(int argc, char *argv[])
{
   QApplication a{argc, argv};
   Window w;
   w.show();
   return a.exec();
}

#include "main.moc"
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有动态变化内容的 QScrollArea 的相关文章

随机推荐

  • 针对 ARM 的 x86?

    是否可以在 ARM 机器上使用 gcc 编译为 x86 我找不到任何 march允许完成此操作的选项 如果无法完成 没什么大不了的 但我仍然有兴趣知道是否可能 是的 但你不需要 march 机器 您想要构建或安装一个以arm为主机架构 以x
  • 基于用户角色渲染 JSF 组件

    如何根据登录用户的角色呈现 JSF 组件 我知道外部上下文公开了原理 但是我应该如何在 JSF 中正确进行渲染 在 JSP 中 它会是这样的
  • 在iPhone上实现蓝牙数据传输

    如何为 iPhone 创建蓝牙应用程序 关于控制器我需要了解什么 委托方法 The GameKit框架包含允许通过蓝牙网络进行通信的 API 使用这些APIs 您可以轻松创建点对点游戏和应用程序 用于访问蓝牙的所有各种 API 都位于Gam
  • leiningen 为什么要建立目录层次结构?我可以放弃它吗?

    如果我使用 leiningen 创建一个新的 clojure 项目 它会生成一个如下所示的目录树 doc intro md project clj README md src hello friend core clj test hello
  • 有没有 MXML 接口之类的东西

    这可能是一个愚蠢的问题 所以如果是的话 请提前道歉 我想知道 MXML 中是否有等效的接口 每当我觉得需要使用界面时 我总是会制作一个动作脚本而不是一个 MXML 文件 因为我不知道是否 如何可以 例如 我打算有一个基于 vbox 的组件
  • jQuery 可拖动选项元素

    关于使以下选项元素可拖动有什么技巧吗
  • 我怎样才能使用javascript保护csv文件的密码

    html 表数据导出到 csv 文件 它正在发生 但我想使用 javascript 对 csv 文件进行密码保护 这可能吗 或其他方法做同样的事情 提前致谢 从表面上看 CSV 文件只是一种数据交换格式 其中字段以逗号分隔 每条记录占一行
  • 如何将参数传递给google cloud build中的docker run

    我正在尝试使用 GCB 运行 cypress 管道 但在 docker 内运行时它崩溃了 如描述的那样解决此问题here https github com cypress io cypress issues 350 是运行 docker i
  • 为什么 `my $x = if (0) {1} else {2}` 不起作用?

    在 Perl 中 x if 0 1 else 2 不起作用 perl E x if 0 1 else 2 syntax error at e line 1 near if Execution of e aborted due to comp
  • 我需要服务器才能使用 git 吗?

    如果我需要在工作或其他地方访问我的家庭计算机上的文件 我是否需要有一个网络服务器并在那里签入文件 如果我正在使用git 我还需要服务器还是我实际上在他们的服务器上保存文件 首先 Git 是分散式版本控制系统 这意味着当使用 Git 时 您在
  • 如何用html5 canvas绘制连续的圆形图案

    我有这个图片 and i want to draw with the image as the pattern When i did i got a result on the canvas like this 但我需要输出是 所以我的问题
  • 如何确认网站正在完全信任地运行?

    我给予了网站完全信任 但我仍然遇到一些安全例外情况 如何确认网站完全信任 您可以使用安全管理器 IsGranted http msdn microsoft com en us library system security security
  • 使用 IAM 帐户时 AppSync 查询返回未经授权

    我正在使用 AWS Amplify 我的 GraphQL 架构中有两个如下所示的模型 type Class model auth rules allow owner identityClaim sub allow owner identit
  • Apache Sling 中的 resourceResolver.adaptTo(Session.class) 的用途是什么?

    我是 Apache Sling CQ5 等的新手 在我们的代码库中 我们有一个与此类似的代码片段 void perform SlingHttpServletRequest request SlingHttpServletResponse r
  • Primefaces textEditor:使用 JavaScript 将文本转换为 HTML 不起作用

    首先我要声明这是我的第一个问题 我是这个社区的新人 请善待我 不要犹豫地纠正我 引导我到哪里可以找到答案或学习等 我发布这个问题是为了找到解决方案的最后希望 因为我自己 也没有在同事的帮助下 没有找到或提出任何解决方案 基本上PrimeFa
  • 引入条件时无法使用 fillna

    我对 python 很陌生 尝试对我的数据进行一些插补 然而 我无法做到 这是简单的代码 df a df loc df c gt 0 df c lt 43 a 1 df loc df c gt 44 df c lt 96 a 2 df lo
  • 如何在 macOS 上安装 dbus-python?

    在第一步 配置时 出现以下错误 checking for DBUS no configure error Package requirements dbus 1 gt 1 6 were not met No package dbus 1 f
  • 将访问过的链接颜色设置为未访问过的链接的颜色(P.S.不是常见问题)

    我需要将 a visited CSS 设置为whatever正常 a 设置的颜色 我希望能够告诉浏览器的是 对于已访问的链接 使用与未访问的链接相同的颜色 无论它是什么颜色 我需要这样做不指定特定颜色 例如 如果出现一些奇怪的浏览器 使用
  • 如何在hadoop中运行jar文件?

    我使用 java 文件创建了一个 jar 文件这个博客 http java dzone com articles hadoop basics creating使用以下语句 javac classpath usr local hadoop h
  • 具有动态变化内容的 QScrollArea

    I have a QScrollArea with some buttons in it like shown on the picture 布局的思路是 1 左右按钮太宽时应使用滚动按钮 2 滚动区域按钮数量可动态改变 3 应利用任何可用