使用QGraphicsProxyWidget将widget绘制在QGraphicsView中

cpp 复制代码
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsItem>
#include <QGraphicsProxyWidget>
#include <QPushButton>
#include <QGraphicsRectItem>
#include <QGraphicsEllipseItem>
#include <QPainter>
#include <QTableWidget>
#include <QHeaderView>
#include <QMenu>
class MyTableWidget : public QTableWidget {
public:
    MyTableWidget(QWidget* parent = nullptr) : QTableWidget(parent) {
        setRowCount(3);    // 设置初始行数
        setColumnCount(3); // 设置初始列数
        resize(m_columnWidth * 3 + 25, m_rowHeight * 3 + 30);
        setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        horizontalHeader()->setStyleSheet("QHeaderView::section{background:white;color: black;}");
        verticalHeader()->setStyleSheet("QHeaderView::section{background:white;color: black;}");
        for (int row = 0; row < 3; ++row) {
            setRowHeight(row, m_rowHeight);
        }
        for (int col = 0; col < 3; ++col) {
            setColumnWidth(col, m_columnWidth);
        }
        // 连接信号与槽
        connect(horizontalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onColumnResized);
        connect(verticalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onRowResized);
    }

protected:
    void contextMenuEvent(QContextMenuEvent* event) override {
        // 创建右键菜单
        QMenu menu(this);

        // 添加"插入行"选项
        QAction* insertRowAction = menu.addAction("Add row");
        connect(insertRowAction, &QAction::triggered, this, &MyTableWidget::insertRowToEnd);

        // 添加"插入列"选项
        QAction* insertColumnAction = menu.addAction("Add column");
        connect(insertColumnAction, &QAction::triggered, this, &MyTableWidget::insertColumnToEnd);

        // 添加"删除行"选项
        QAction* deleteRowAction = menu.addAction("Delete row");
        connect(deleteRowAction, &QAction::triggered, this, &MyTableWidget::deleteRow);

        // 添加"删除列"选项
        QAction* deleteColumnAction = menu.addAction("Delete column");
        connect(deleteColumnAction, &QAction::triggered, this, &MyTableWidget::deleteColumn);

        // 执行右键菜单
        menu.exec(event->globalPos());
    }

private slots:
    void onColumnResized(int logicalIndex, int oldSize, int newSize) {
        int size = newSize - oldSize;
        resize(width() + size, height());
    }

    void onRowResized(int logicalIndex, int oldSize, int newSize) {
        int size = newSize - oldSize;
        resize(width(), height() + size);
    }
    void deleteRow() {
        if (rowCount() == 1)
            return;
        int row = currentRow(); // 获取当前行数
        int h = rowHeight(row);
        removeRow(row);
        resize(width(), height() - h);
    }
    void deleteColumn() {
        if (columnCount() == 1)
            return;
        int column = currentColumn(); // 获取当前列数
        int w = columnWidth(column);
        removeColumn(column);
        resize(width() - w, height());
    }
    void insertRowToEnd() {
        // 禁用信号连接
        disconnect(verticalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onRowResized);
        int row = rowCount(); // 获取当前行数
        insertRow(row);       // 插入新行到表格末尾
        setRowHeight(row, m_rowHeight);
        resize(width(), height() + m_rowHeight);
        connect(verticalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onRowResized);
    }

    void insertColumnToEnd() {
        // 禁用信号连接
        disconnect(horizontalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onColumnResized);
        int column = columnCount(); // 获取当前列数
        insertColumn(column);       // 插入新列到表格末尾
        setColumnWidth(column, m_columnWidth);
        resize(width() + m_columnWidth, height());
        connect(horizontalHeader(), &QHeaderView::sectionResized, this, &MyTableWidget::onColumnResized);
    }

private:


public:
    int m_columnWidth = 80;
    int m_rowHeight = 30;

};
class MyGraphicsItem :public QGraphicsItem
{
public:
    MyGraphicsItem(QGraphicsItem* parent = nullptr) :QGraphicsItem(parent)
    {
        m_proxyWidget = new QGraphicsProxyWidget(this);
        m_tableWidget = new MyTableWidget();
        m_proxyWidget->setWidget(m_tableWidget);

    }
    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = nullptr) override
    {
        QPen paintPen(Qt::black);
        painter->setPen(paintPen);
        painter->setBrush(Qt::NoBrush);
        painter->drawRect(m_tableWidget->rect());
        //m_proxyWidget->paint(painter, option, m_tableWidget);
        //m_proxyWidget->widget()->render(painter, m_tableWidget->rect().topLeft(), m_tableWidget->rect());
        //m_tableWidget->render(painter, m_tableWidget->rect().topLeft(), m_tableWidget->rect());
    }
    virtual QRectF boundingRect() const override
    {
        return m_tableWidget->rect();
    }
private:
    QGraphicsProxyWidget* m_proxyWidget = nullptr;
    MyTableWidget* m_tableWidget = nullptr;
    QRectF m_rect;
};
int main(int argc, char* argv[])
{
    QApplication app(argc, argv);

    // 创建 QGraphicsScene 和 QGraphicsView
    QGraphicsScene* scene = new QGraphicsScene();
    QGraphicsView* view = new QGraphicsView(scene);
    view->setRenderHint(QPainter::Antialiasing);
    view->setRenderHint(QPainter::SmoothPixmapTransform);

    // 创建图形项并添加到场景
    MyGraphicsItem* item = new MyGraphicsItem();
    scene->addItem(item);
    scene->setSceneRect(-50, -50, 1000, 1000);
    // 设置视图
    view->setScene(scene);
    view->resize(600, 800);
    view->show();


    return app.exec();
}

上面是一个例子,使用QGraphicsProxyWidget将QTableWidget绘制在QGraphicsView中

该表格可以拖动行宽和列高并且不显示滚动条,自动调整大小,也可以右键增加行或者列

需要注意的是,在使用QGraphicsProxyWidget时,如果调用MyGraphicsItem 的paint方法无法显示QTableWidget时,需要显示调用QGraphicsProxyWidget的paint方法才能显示,或者直接调用widget的render方法来进行绘制

cpp 复制代码
m_proxyWidget->paint(painter, option, m_tableWidget);
m_proxyWidget->widget()->render(painter, m_tableWidget->rect().topLeft(), m_tableWidget->rect());
m_tableWidget->render(painter, m_tableWidget->rect().topLeft(), m_tableWidget->rect());

调用上面任一条语句即可

相关推荐
踏过山河,踏过海1 天前
【用ui文件做个简单工具的开发,为什么修改完ui后,程序重新编译运行后,GUI界面还是不变呢?】
qt·ui
向阳开的夏天1 天前
麒麟V10源码编译QT5.6.3 (x86 & arm64)
开发语言·qt
打码的猿1 天前
Qt对话框不锁死主程序的方法
开发语言·qt
小小码农Come on1 天前
Qt Creator常用设置
qt
wkm9561 天前
在arm64 ubuntu系统安装Qt后编译时找不到Qt3DExtras头文件
开发语言·arm开发·qt
小小码农Come on1 天前
QT开发环境安装
开发语言·qt
小小码农Come on1 天前
QT内存管理
开发语言·qt
有理想的打工人1 天前
QT的安装
qt
SilentSlot2 天前
【QT-QML】8. 输入元素
qt·qml
是店小二呀2 天前
Visual Studio C++ 工程架构深度解析:从 .vcxproj 到 Qt MOC 的文件管理实录
c++·qt·visual studio