这是我的问题,我使用setGeometry()方法手动显示“按钮和标签”。

从QWidget继承的MyClass

这是我的代码:

void MyClass::function() {
QLabel *imgP;
  QLabel *name;
  QPushButton *newConv;
  QPixmap *profilPic;

  std::stringstream ss;
  int j = 0;
  int i = 0;
  for (int tmp = 0; tmp < 15; tmp++)
    {
      if (i % 7 == 0 && i != 0)
        {
          i = 0;
          j++;
        }
      ss << "Username " << tmp;
      name = new QLabel(tr(ss.str().c_str()), this);
      name->setAlignment(Qt::AlignCenter);
      name->setGeometry((30 * (i + 1) + 240 * i), (30 + 390 * j),
                        240, 60);
      profilPic = new QPixmap("./gui/img/avatar1.png");
      imgP = new QLabel(this);
      imgP->setPixmap(profilPic->scaled(240, 240));
      imgP->setGeometry((30 * (i + 1) + 240 * i), (90 + 390 * j),
                        240, 240);
      newConv = new QPushButton(tr("Chat"), this);
      newConv->setGeometry((30 * (i + 1) + 240 * i), (330 + 390 * j),
                           240, 60);
      newConv->setFocusPolicy(Qt::NoFocus);
      connect(newConv, SIGNAL(released()), this, SLOT(addTab()));

      ss.str("");
      ss.clear();
      i++;
    }
}


它可能比它应该的要复杂一些,但它的工作方式正是我想要的..

它看起来像这样:

c&#43;&#43; - 可滚动的 View 作为TabWidget-LMLPHP

如您所见,结果很好,显示了我的联系人,但是第15个元素被隐藏了,因为窗口太小了。所以我的问题是:

发生这种情况时,如何制作ScrollView?
我已经知道QScrollArea,但是我必须与QBoxLayout一起工作,我认为这不会做。

谢谢你的帮助 !

编辑

这是我的MainWidget类,它显示窗口:

class QTabBar;

MainWidget::MainWidget(QWidget *parent) : QWidget(parent)
{
  setFixedSize(1920, 1200);
  setWindowTitle(tr("Babel"));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  QTabBar *tb;

  UiContact *contact = new UiContact(this);
  QScrollArea *contactScrollArea = new QScrollArea();
  contactScrollArea->setWidget(contact);

  _tabWidget = new QTabWidget;
  tb = _tabWidget->tabBar();

  _tabWidget->addTab(new Home(), tr("Home"));
  _tabWidget->addTab(contactScrollArea, tr("Contact"));

  std::ostringstream oss;

  _tabWidget->setTabsClosable(true);
  connect(_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));

  tb->tabButton(0, QTabBar::RightSide)->hide();
  tb->tabButton(1, QTabBar::RightSide)->hide();

  _tabWidget->setFocusPolicy(Qt::NoFocus);

  mainLayout->addWidget(_tabWidget);
  setLayout(mainLayout);
}

最佳答案

QScrollArea当然是要走的路。不必使用布局,只需要强制将小部件设置为所需的大小即可。 QScrollArea可以处理任何QWidget派生类,并且将根据需要显示其滚动条。

实际上:如果您可以计算需要多少空间(我想您可以做到),并相应地设置包含的小部件的大小约束,则QScrollArea将自动显示滚动条。您可以将QWidget::setMinimumSize用于该目的,一个简单的setMinimumSize(itemWidth*7,itemHeight*(count%7))就足够了。

此方法的确允许窗口小部件增大到足以填充QScrollArea的程度。此外,如果愿意,可以禁用QScrollArea周围的框。

编辑:

您可能有这样的事情:

MyClass *myClass = new MyClass();

...

tabs->insertTab(1,myClass,"Contact");


在这种情况下的示例实现为:

MyClass *myClass = new MyClass();

...

QScrollArea* contactScrollArea = new QScrollArea();
contactScrollArea->setWidget(myClass);
tabs->insertTab(1,contactScrollArea,"Contact");


它将在标签小部件内放置一个滚动区域,并将MyClass实例放入其中

QScrollArea用作相对较高的容器类。将QScrollArea视为可以在其中嵌入另一个小部件的小部件。默认情况下,它将创建一个空的小部件,该小部件可以获取布局。但是通过使用setWidget,您可以在字面上放置任何想要的东西。可能的“组合”是带有较大许可证文本的QLabel或任何其他可能会变得太大的小部件(例如您的小部件)。

现在,仅提供一些额外信息:

当您自己绘制内容(而不是创建多个小部件并编写自己的布局内容)时,可以使用QAbstractScrollArea。这样可以完全控制您。它提供了滚动条和一个单独的中间小部件,您可以在paintEvent期间将其绘制到其中。但是我认为这超出了此范围。

现在,为了简洁的编码。我实际上建议您创建一个单独的类ContactItem。它由标签,图像和按钮组成,并与QVBoxLayout保持在一起(使它们整齐地包装在彼此之上)。该“项目”可以放在QGridLayout中。这样,您就不必担心安排项目。如果您在图片上设置了最小尺寸,则将确保这些项目是您喜欢的宽度/高度。标签大小限制确保字体差异不会影响显示(按钮也是如此)。最后但并非最不重要的一点是,您的列表突然可以调整大小。 (通过使用setRowStretchsetColumnStretch,可以确保列表居中或顶部对齐,以防窗口大于列表占用的窗口。

功能解释

在这里,我可以从屏幕快照和给定的代码中得到一个可能的实现(这不是我最好的代码)。

c&#43;&#43; - 可滚动的 View 作为TabWidget-LMLPHP

它由一个“小部件”组成,该小部件负责标签的布局:

mainwidget.h

#include <QWidget>
#include "uicontact.h"

class QTabWidget;

class MainWidget : public QWidget
{
  Q_OBJECT

  QTabWidget *_tabWidget;

public:
  MainWidget(QWidget *parent = 0);
  ~MainWidget();

public slots:
  void addChatTab();
};


mainwidget.cpp

#include "mainwidget.h"

#include <QScrollArea>

#include <QTabWidget>
#include <QTabBar>
#include <QVBoxLayout>

#include "home.h"

MainWidget::MainWidget(QWidget *parent)
  : QWidget(parent)
{
  setFixedSize(1920,1200);
  setWindowTitle(tr("Babel"));

  QVBoxLayout *mainLayout = new QVBoxLayout;
  QTabBar *tb;

  UiContact *contact = new UiContact(this);
  QScrollArea *contactScrollArea = new QScrollArea();
  contactScrollArea->setWidget(contact);

  _tabWidget = new QTabWidget;
  tb = _tabWidget->tabBar();

  _tabWidget->addTab(new Home(), tr("Home"));
  _tabWidget->addTab(contactScrollArea, tr("Contact"));

  _tabWidget->setTabsClosable(true);
  connect(_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTab(int)));

  tb->tabButton(0, QTabBar::RightSide)->hide();
  tb->tabButton(1, QTabBar::RightSide)->hide();

  _tabWidget->setFocusPolicy(Qt::NoFocus);

  mainLayout->addWidget(_tabWidget);
  setLayout(mainLayout);
}

MainWidget::~MainWidget()
{

}

void MainWidget::addChatTab()
{
  _tabWidget->addTab(new QWidget, tr("Number %1").arg(_tabWidget->count()-2));
}


MyClass类负责创建“联系人”标签:

uicontact.cpp

#include "uicontact.h"

#include "mainwidget.h"

#include <QLabel>
#include <QPushButton>

UiContact::UiContact(MainWidget *owner,QWidget *parent) : QWidget(parent)
{
  QLabel *imgP;
  QLabel *name;
  QPushButton *newConv;
  QPixmap *profilPic;

  int j = 0;
  int i = 0;
  for (int tmp = 0; tmp < 15; tmp++)
    {
      if (i % 7 == 0 && i != 0)
        {
          i = 0;
          j++;
        }

      name = new QLabel(tr("Username %1").arg(tmp), this);
      name->setAlignment(Qt::AlignCenter);
      name->setGeometry((30 * (i + 1) + 240 * i), (30 + 390 * j),
                        240, 60);
      profilPic = new QPixmap("./gui/img/avatar1.png");
      imgP = new QLabel(this);
      imgP->setPixmap(profilPic->scaled(240, 240));
      imgP->setGeometry((30 * (i + 1) + 240 * i), (90 + 390 * j),
                        240, 240);
      newConv = new QPushButton(tr("Chat"), this);
      newConv->setGeometry((30 * (i + 1) + 240 * i), (330 + 390 * j),
                           240, 60);
      newConv->setFocusPolicy(Qt::NoFocus);
      connect(newConv, SIGNAL(clicked(bool)), owner, SLOT(addChatTab()));

      i++;
    }

  setMinimumSize(270*7,420*(15/7+1));
}


uicontact.h文件非常简单,因此省略。

需要注意的几件事:MyClass收到一个“所有者”指针,这使它可以直接与负责添加标签的顶级窗口小部件对话。可能您想查看QSignalMapper以便能够将各个QPushButton映射到一个更知名的值。使用QSignalMapper,可以将按钮映射到整数,字符串,QWidget*QObject*

还要注意tr("Contact %1").arg(tmp),这是使程序知道语言环境的正确方法。

关于c++ - 可滚动的 View 作为TabWidget,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33526721/

10-10 21:22