首页 > 解决方案 > 如何调整 qt 停靠小部件的大小以适合 qCustomPlot 小部件?

问题描述

包含 qCustomPlot 的 qDockWidget 始终以零高度开始。我能够捕获 qDockWidget 调整大小事件并使用这些 答案更改 qCustomPlot 几何图形,但 qCustomPlot 在手动拉伸之前始终处于隐藏状态。这应该自动发生,还是我需要在启动时计算和设置停靠高度?

此示例代码创建一个新的 qCustomPlot 小部件,将其放置在布局中,将该布局放置在另一个小部件中,并将其设置为停靠栏。我还尝试将 qCustomPlot 小部件直接放入 Dock 中。qCustomPlot setGeometry、setMinimumSize 和 setSizePolicy 似乎对停靠高度没有影响。

#include <QMainWindow>
#include "qcustomplot.h"


class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(){
        QCustomPlot *m_customPlot;
        QDockWidget *dock;

        resize(1200, 600);

        //create the plot
        QWidget *plot_frame_temp= new QWidget();
        plot_frame_temp->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding);
        m_customPlot = new QCustomPlot(plot_frame_temp);
        m_customPlot->axisRect()->setupFullAxesBox(true);
        m_customPlot->setBackground(Qt::black);
        //size and margin settings
        m_customPlot->setGeometry(QRect(0, 0, 500, 400));
        m_customPlot->axisRect()->setMinimumSize(500,400);
        m_customPlot->axisRect()->setAutoMargins(QCP::msLeft|QCP::msBottom|QCP::msRight|QCP::msTop);
        // zoom and drag only on horrizontal axis
        m_customPlot->axisRect()->setRangeZoomAxes(m_customPlot->xAxis,nullptr);
        m_customPlot->axisRect()->setRangeDragAxes(m_customPlot->xAxis,nullptr);
        //setup the top axis and labels
        m_customPlot->xAxis->setVisible(false);
        m_customPlot->xAxis2->setVisible(true);
        m_customPlot->xAxis2->setTicks(true);
        m_customPlot->xAxis2->setTickLabels(true);
        m_customPlot->xAxis2->setTickPen(QColor(136, 136, 136));
        m_customPlot->xAxis2->setTickLength(0,10);
        m_customPlot->xAxis2->setTickLabelColor(QColor(136, 136, 136));
        m_customPlot->xAxis2->setSubTickPen(Qt::NoPen);
        m_customPlot->xAxis2->setBasePen(Qt::NoPen);
        QFont font;
        font.setStyleStrategy(QFont::PreferOutline);
        m_customPlot->xAxis2->setTickLabelFont(font);
        //setup the left axis and hide
        m_customPlot->yAxis->setVisible(false);
        m_customPlot->yAxis->setRangeReversed(true);
        m_customPlot->yAxis2->setVisible(false);
        //first graph
        m_customPlot->addGraph();
        m_customPlot->graph()->setPen(QPen(QColor(165, 165, 165)));
        m_customPlot->graph()->setLineStyle((QCPGraph::lsStepLeft));
        //second graph
        m_customPlot->addGraph();
        m_customPlot->graph()->setPen(QPen(QColor(165, 165, 165)));
        m_customPlot->graph()->setLineStyle((QCPGraph::lsStepLeft));
        // make some data
        QVector<double> x(500), y0(500), y1(500);
        for (int i=0; i<500; ++i)
        {
        x[i] = i;
        y0[i] = (rand() % 2 + 0.2)/2;
        y1[i] = (rand() % 2 + 1.4)/2;
        }
        //add data to graph
        m_customPlot->graph(0)->setData(x, y0);
        m_customPlot->graph(1)->setData(x, y1);
        // set some options
        m_customPlot->setNotAntialiasedElements(QCP::aeAll);
        m_customPlot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);

        //add plot widget to layout
        QHBoxLayout *laLayout = new  QHBoxLayout();
        laLayout->addWidget(plot_frame_temp);

        //add layout to another widget
        QWidget *laWidget=new QWidget();
        laWidget->setLayout(laLayout);

        //add second widget to dock
        dock = new QDockWidget(tr("qcustomplot"), this);
        dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
        dock->setWidget(laWidget);

        addDockWidget(Qt::BottomDockWidgetArea, dock);

        QWidget *centralWidget=new QWidget();
        setCentralWidget(centralWidget);
    }

};

这是直接在 mainwindow.h 中完成的最小示例。带有中央小部件的停靠栏和带有 qCustomPlot 的 QDockWidget。我正在使用 qCustomPlot 的已编译 DLL 版本

图片:码头从零高度开始:

在此处输入图像描述

最初码头看起来像这样。情节被隐藏,码头在其他空的布局中声称没有高度。

图片:码头拉伸以显示情节

在此处输入图像描述

当用户拉伸扩展坞时,该图可见。

我强烈怀疑码头有一种方法可以自动调整到 qCustomPlot 的高度。我可以从代码中设置停靠高度,但这似乎是一个 hack。

标签: qtqcustomplot

解决方案


解决您的问题的最直接方法可能是为您的 QCustomPlot 小部件定义最小尺寸。这可以通过以下简化示例轻松实现。实际上,这些问题根本与 QCustomPlot 无关。它可能是具有最小尺寸 (0,0) 的任何类型的小部件。

#include <QMainWindow>
#include "qcustomplot.h"

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(){
        auto m_customPlot = new QCustomPlot();
        m_customPlot->axisRect()->setupFullAxesBox(true);

        auto dock = new QDockWidget(tr("qcustomplot"), this);
        dock->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
        dock->setWidget(m_customPlot);
        m_customPlot->setMinimumSize(QSize(500,500));
        dock->setMinimumSize(m_customPlot->minimumSize());
        addDockWidget(Qt::DockWidgetArea::BottomDockWidgetArea, dock);

        setCentralWidget(new QWidget);
    }

};

更好的解决方案可能是在注册表中保存和恢复停靠小部件配置的几何形状。这使用户只剩下他认为需要的停靠小部件配置。

void MainWindow::closeEvent(QCloseEvent *event)
{
    QSettings settings("MyCompany", "MyApp");
    settings.setValue("geometry", saveGeometry());
    QMainWindow::closeEvent(event);
}

QSettings settings("MyCompany", "MyApp");
dock->restoreGeometry(settings.value("myWidget/geometry").toByteArray());

推荐阅读