使用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());

调用上面任一条语句即可

相关推荐
唐墨1233 小时前
android与Qt类比
android·开发语言·qt
道剑剑非道4 小时前
QT开发技术【ffmpeg + QAudioOutput】音乐播放器 完善
开发语言·qt·ffmpeg
不惑_5 小时前
用 PyQt5 打造一个可视化 JSON 数据解析工具
开发语言·qt·json
誰能久伴不乏12 小时前
Qt 开发中的父类与父对象的区别和父对象传递:如何选择 `QWidget` 或 `QObject`?
java·开发语言·qt
誰能久伴不乏12 小时前
理解继承与组合的本质:Qt 项目中的设计选择指南
开发语言·qt
抠脚学代码17 小时前
Ubuntu18.6 学习QT问题记录以及虚拟机安装Ubuntu后的设置
qt·学习·ubuntu
小道士写程序1 天前
Qt 5.12 上读取 .xlsx 文件(Windows 平台)
开发语言·windows·qt
yxc_inspire1 天前
基于Qt的app开发第十三天
c++·qt·app·tcp·面向对象
潇-xiao1 天前
Qt 按钮类控件(Push Button 与 Radio Button)(1)
c++·qt
追风赶月、1 天前
【QT】认识QT
开发语言·qt