26

我刚刚开始研究一个新的 C++/Qt 项目。这将是一个基于 MDI 的 IDE,带有用于文件树、对象浏览器、编译器输出等内容的停靠小部件。但到目前为止,有一件事困扰着我:我不知道如何以编程方式使一个QDockWidget更小。例如,这个片段创建了我的底部停靠窗口,“构建信息”:

m_compilerOutput = new QTextEdit;
m_compilerOutput->setReadOnly(true);
dock = new QDockWidget(tr("Build Information"), this);
dock->setWidget(m_compilerOutput);
addDockWidget(Qt::BottomDockWidgetArea, dock);

启动时,我的程序如下所示(记住开发的早期阶段):

实际的

但是,我希望它看起来像这样:

预期的

我似乎无法让这件事发生。QDockWidget 上的 Qt 参考是这样说的:

应在子小部件中实施自定义尺寸提示、最小和最大尺寸以及尺寸策略。QDockWidget 将尊重它们,调整自己的约束以包括框架和标题。不应在 QDockWidget 本身上设置大小约束,因为它们会根据它是否停靠而改变

现在,这表明进行此操作的一种方法是子类化QTextEdit并覆盖该sizeHint()方法。但是,我不想仅仅为了这个目的而这样做,我也没有尝试过它来找到一个可行的解决方案。

我已经尝试调用dock->resize(m_compilerOutput->width(), m_compilerOutput->minimumHeight()),调用m_compilerOutput->setSizePolicy()它的每个选项......到目前为止没有任何影响大小。就像我说的那样,我更喜欢用几行代码提供一个简单的解决方案,而不是必须创建一个子类来更改sizeHint(). 所有建议表示赞赏。

4

9 回答 9

9

我让它变得简单:标题:

private void setDockSize(QDockWidget *dock, int, int);
  public slots:
  void returnToOldMaxMinSizes();

来源:

QSize oldMaxSize, oldMinSize;

void MainWindow::setDockSize(QDockWidget* dock, int setWidth,int setHeight)
{

    oldMaxSize=dock->maximumSize();
    oldMinSize=dock->minimumSize();

  if (setWidth>=0)
    if (dock->width()<setWidth)
        dock->setMinimumWidth(setWidth);
    else dock->setMaximumWidth(setWidth);
  if (setHeight>=0)
    if (dock->height()<setHeight)
        dock->setMinimumHeight(setHeight);
    else dock->setMaximumHeight(setHeight);

    QTimer::singleShot(1, this, SLOT(returnToOldMaxMinSizes()));
}

void MainWindow::returnToOldMaxMinSizes()
{
    ui->dockWidget->setMinimumSize(oldMinSize);
    ui->dockWidget->setMaximumSize(oldMaxSize);
}
于 2012-03-25T17:04:34.157 回答
7

这是一个老问题,但我想提一下 Qt 5.6 引入了QMainWindow::resizeDocks函数来处理这个问题。

不幸的是,它不适用于我的用例(在使用 QMainWindows::splitDockWidget 拆分的两个 QDockWidget 之间移动分隔符)

于 2017-02-24T04:47:06.737 回答
6

考虑到它的子小部件,听起来停靠小部件将自身重新调整为适当的大小。从 QDockWidget 文档(强调我的):

QDockWidget 充​​当其子部件的包装器,使用 setWidget() 设置。自定义尺寸提示、最小和最大尺寸以及尺寸策略应在子小部件中实现。QDockWidget 将尊重它们,调整自己的约束以包括框架和标题。不应在 QDockWidget 本身上设置大小约束,因为它们会根据它是否停靠而改变;停靠的 QDockWidget 没有框架和较小的标题栏。

为了更改大小,您必须重新调整子小部件的大小。

编辑:Qt 文档在讨论尺寸提示时有时会产生误导。通常,它指的是任何类型的调整大小,无论是由小部件自动执行还是以编程方式执行。

于 2010-05-05T19:52:11.933 回答
5

我刚刚经历了同样的过程。在尝试了太多关于停靠小部件及其包含的小部件的resize(),和朋友的排列之后,这些都没有奏效,我最终继承并添加了该方法。adjustSize()QListViewsizeHint()

现在它就像一个魅力。

于 2013-05-22T14:38:48.430 回答
2

您是否尝试过调用您resize()QTextEdit停靠小部件内部?您也可以尝试暂时将停靠小部件的最大和最小尺寸设置为您想要的尺寸,然后恢复原始值。

于 2010-05-02T01:50:25.320 回答
2

你可以这样做:

设置您的最大高度QTextEdit

m_compilerOutput = new QTextEdit;
m_compilerOutput->setMaximumHeight(100);

然后在主窗口的显示事件中将其设置回旧大小或更高的大小:

void MainWindow::showEvent(QShowEvent *)
{
   m_compilerOutput->setMaximumHeight(10000);
}

这就是你所需要的。

于 2013-05-23T07:06:46.300 回答
1

QDockWidget::widget()在(即管理的小部件)上使用调整大小的测试QDockWidget并不能始终按预期工作。

对于一个QDockWidget子类 (DW),其中 aQWidget和 a 添加QHBoxLayout了两个小部件(左面板和右面板),所有这些小部件的大小策略都设置为QSizePolicy::Minimum,DW 通常具有两个面板小部件可见。当 DW 位于侧坞时,QMainWindow处理 DW 信号的应用程序 ( ) 插槽会dockLocationChanged隐藏左侧面板并重新调整DW->widget()到尺寸右侧面板。当 DW 以编程方式移动到底部停靠区域时,leftPanel 设置为可见并且 DW 填充主窗口的整个宽度(当然)。然后,当 DW 以编程方式移动到侧停靠区域时,左侧面板被隐藏,并且 DW 被重新调整大小。这按预期工作。但是,如果将 DW 从底部停靠区域拖到侧面停靠区域,尽管左侧面板被隐藏并且像以前一样应用了重新调整大小,但 DW 不会像以编程方式完成重新定位时那样重新调整大小。可以通过在 DW 和主窗口中心区域之间拖动拆分器手柄来手动缩小 DW 的大小。请注意,主窗口中心区域是一个QWidget具有QHBoxLayout大小策略的区域QSizePolicy::Expanding

adjustSize调整 DW 大小后调用主窗口无效。尽管 DW 已重新实现sizeHint以根据左侧面板是否可见返回其最小尺寸,但仍然如此。

要么我在如何控制大小方面遗漏了一些东西QDockWidget(鉴于我很难理解布局管理系统各部分之间的所有交互,很可能),或者QMainWindow忽略或覆盖了布局指令它正在被给予。在重新定位操作期间仔细检查事件流QDockWidget表明后者:在处理dockLocationChanged信号的插槽完成其大小调整工作并返回到事件循环后,我可以看到QMainWindow,当用户重新定位完成时,对受影响QDockWidget,从而撤消尝试控制扩展坞大小的应用程序逻辑。似乎有些不对劲QMainWindow......

于 2011-05-13T06:50:06.917 回答
1

如果dockWidgets 是停靠的,则尺寸由它们的父级控制。在这种情况下,您可以使用该QMainWindow::resizeDocks功能。

如果浮动,则大小由其子级确定。调整孩子的大小以实现您的目的。

于 2017-04-28T07:16:29.343 回答
0

QTBUG-16252 ( https://bugreports.qt.io/browse/QTBUG-16252 )中描述了 MainWindow 最大化时停靠小部件的大小调整问题

我找到了另一种解决方法。在 Windows7 上的 QT 5.4.1 minGW 上为我工作。看起来一些小部件状态恢复操作与 QApplication 事件循环密切相关。

仅当满足以下条件时,DockWidget 大小才能正确恢复:

  1. 在进入 QApplication::exec() 之前调用 restoreGeometry() (例如在 MainWindow 类的构造函数中)

  2. restoreState() 在 exec() 之后被调用(例如通过 QTimer)

这是我的代码:

int main(int argc, char *argv[])
{
    QApplication application(argc, argv);

    //...

    MainWindow mainWindow;
    mainWindow.show();

    return application.exec();
}

MainWindow::MainWindow(...) 
{
    ui->setupUi(this);

    //...
    QTimer* nt = new QTimer(this);

    nt->setSingleShot(true);
    nt->setInterval( 100 );

    connect(nt, SIGNAL(timeout()), SLOT(restoreWidgetSettings()));
    nt->connect(nt, SIGNAL(timeout()), SLOT(deleteLater()));

    nt->start();

    restoreWidgetSettings(true);
}

void MainWindow::restoreWidgetSettings(bool geometryOnly) {

    //...
    QByteArray geometry = getSettings();

    restoreGeometry(geometry);

    if(geometryOnly)
        return;

    //... //create dock widgets here

    restoreState(mainWindowState);

}
于 2015-05-15T09:40:16.760 回答