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());
调用上面任一条语句即可