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

调用上面任一条语句即可

相关推荐
feiyangqingyun2 小时前
Qt监控系统远程网络登录/请求设备列表/服务器查看实时流/回放视频/验证码请求
服务器·网络·qt
冷眼看人间恩怨5 小时前
【Qt笔记】QTextEdit和QPlainTextEdit 控件详解
c++·笔记·qt
17´17 小时前
使用QT+OpenCV+C++完成一个简单的图像处理工具
c++·图像处理·qt·opencv
Yungoal17 小时前
用QT实现 端口扫描工具1
qt
美丽的欣情17 小时前
Qt实现海康OSD拖动Demo
开发语言·qt
qincjun20 小时前
Qt仿音乐播放器:数据库持久化
开发语言·数据库·qt
-凌凌漆-1 天前
【Qt】C++11 Lambda表达式
qt
清醒的兰1 天前
Qt 样式表
开发语言·qt
我想学LINUX1 天前
【STM32+QT项目】基于STM32与QT的智慧粮仓环境监测与管理系统设计(完整工程资料源码)
stm32·嵌入式硬件·qt·毕业设计·课程设计·项目开发