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

调用上面任一条语句即可

相关推荐
少控科技6 小时前
QT新手日记028 QT-QML所有类型
开发语言·qt
hqwest8 小时前
码上通QT实战37--项目总结
开发语言·qt·软件开发·系统集成·设备选型
少控科技9 小时前
QT新手日记026
开发语言·qt
嘿嘿潶黑黑9 小时前
绘图中 QRect 与 QRectF 的不同
qt
木千10 小时前
Qt全屏显示,在顶部工具栏的最右边显示关闭按钮
开发语言·qt
誰能久伴不乏11 小时前
Qt 线程为什么和 Linux pthread 不一样?事件循环、QObject 线程归属与串口上位机正确架构
linux·qt·架构
少控科技11 小时前
QT新手日记025 - W002程序代码
开发语言·qt
C++ 老炮儿的技术栈11 小时前
Qt中自定义 QmyBattery 电池组件开发
c语言·开发语言·c++·windows·qt·idea·visual studio
少控科技14 小时前
QT新手日记 029 - QT所有模块
开发语言·qt
少控科技1 天前
QT高阶日记01
开发语言·qt