代码之家  ›  专栏  ›  技术社区  ›  Olli Savolainen

如何在Qt桌面应用程序中拥有SVG背景,以便缩放窗口保持小部件与SVG坐标的完整性

  •  0
  • Olli Savolainen  · 技术社区  · 1 年前

    我正在开发一个Qt桌面应用程序,希望将SVG作为背景。调整窗口大小时,UI中的小部件应保持在相对于SVG坐标的位置。

    我已经使用加载了SVG和UI QUiLoader 并将SVG设置为背景。

    然而,当我调整窗口的大小时,小部件不会保持它们相对于SVG背景的位置。

    如何确保窗口大小调整时小部件和SVG一起缩放并保持它们的相对位置?

    以下是我的代码片段:

    
    
    QGraphicsSvgItem *svgItem = new QGraphicsSvgItem(":/vectorised-color2.svg");
    scene->addItem(svgItem);
    view->setScene(scene);
    setCentralWidget(view);
    
    QFile file(":/view.ui");
    file.open(QFile::ReadOnly);
    
    QUiLoader loader;
    QWidget *widget = loader.load(&file, this);
    // ... add widget to scene
    
    widget->resize(svgBounds.width(), svgBounds.height());
    
    
    
    1 回复  |  直到 1 年前
        1
  •  0
  •   user17726418 Shajeen Ahamed    1 年前

    加载相同 .ui 文件通过 QUILoader 做到了这一点,使用SVG缩放UI。我不知道为什么。如果您加载单独的 .ui 文件,这似乎不起作用。

    #include "mainwindow.h"
    #include <QFile>
    #include <QGraphicsProxyWidget>
    #include <QGraphicsScene>
    #include <QGraphicsSvgItem>
    #include <QGraphicsView>
    #include <QtUiTools/QUiLoader>
    #include "./ui_mainwindow.h"
    #include "resizinggraphicsview.h"
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        QWidget *spacer = new QWidget(this);
        spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
        ui->toolBar->addWidget(spacer);
        ui->toolBar->addAction(ui->actionAbout);
    
        ResizingGraphicsView *view = new ResizingGraphicsView(this);
        view->setResizeAnchor(QGraphicsView::AnchorViewCenter);
        view->setTransformationAnchor(QGraphicsView::AnchorViewCenter);
        QGraphicsScene *scene = new QGraphicsScene();
        QGraphicsSvgItem *svgItem = new QGraphicsSvgItem(":/vectorised-color2.svg");
    
        scene->addItem(svgItem);
        view->setScene(scene);
        setCentralWidget(view);
    
        QFile file(":/mainwindow.ui");
        file.open(QFile::ReadOnly);
    
        QUiLoader loader;
        QWidget *widget = loader.load(&file, this);
    
        removeToolbarAndStatusBar(widget);
        QRectF svgBounds = svgItem->boundingRect();
        widget->resize(svgBounds.width(), svgBounds.height());
        file.close();
        widget->setAttribute(Qt::WA_TranslucentBackground);
        QGraphicsProxyWidget *proxy = scene->addWidget(widget);
        proxy->setAutoFillBackground(false);
    
        // signals need to be explicitly connected
        QPushButton *pushButton = widget->findChild<QPushButton *>("pushButton");
        if (pushButton) {
            connect(pushButton, &QPushButton::clicked, this, &MainWindow::clickbutton);
        }
    }
    
    /*
     * This is a hack: For some reason by loading the SAME .ui file (mainwindow),
     * widgets resize in sync while keeping the svg image centered
     * But without this we would get duplicated toolbar and statusbar
     * */
    
    void MainWindow::removeToolbarAndStatusBar(QWidget *widget)
    {
        QToolBar *toolbar = widget->findChild<QToolBar *>("toolBar");
        if (toolbar) {
            toolbar->hide(); // or delete toolbar;
        }
        QStatusBar *statusBar = widget->findChild<QStatusBar *>("statusbar");
        if (statusBar) {
            statusBar->hide(); // or delete statusBar;
        }
    }
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::clickbutton()
    {
        qDebug() << "button click";
    }
    

    注意事项:

    • 如果您有工具栏或状态栏,则需要手动隐藏它们。

    • 您需要手动连接来自UI小部件的信号。