使用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 小时前
用 Turbo Vision 2 为 Qt 6 控制台应用创建 TUI 字符 MainFrame
开发语言·c++·qt·tui·字符界面·curse
charlie1145141912 小时前
深入理解Qt的SetWindowsFlags函数
开发语言·c++·qt·原理分析
醇醛酸醚酮酯4 小时前
Qt项目锻炼——TODO清单(二)
开发语言·数据库·qt
Mr_Xuhhh5 小时前
信号与槽的总结
java·开发语言·数据库·c++·qt·系统架构
灵性花火7 小时前
Qt的前端和后端过于耦合(0/7)
开发语言·前端·qt
菜鸟看点16 小时前
自定义Cereal XML输出容器节点
c++·qt
漫步企鹅16 小时前
【蓝牙】Linux Qt4查看已经配对的蓝牙信息
linux·qt·蓝牙·配对
new_zhou17 小时前
Windows qt打包编译好的程序
开发语言·windows·qt·打包程序
看到我,请让我去学习1 天前
Qt编程-qml操作(js,c++,canvas)
开发语言·qt
哈市雪花1 天前
相机:Camera原理讲解(使用OpenGL+QT开发三维CAD)
qt·3d·交互·相机·图形学·opengl·视角