C++ Qt将许多QGraphicsPixmapItem添加到QGraphicscene中
我试图创建一个像大多数照片编辑器程序(Photoshop)一样的图层系统,我基本上使用QGraphicsPixmapItem::setPixmap(QPixmap*图像)绘制一个QGraphicsPixmapItem;在QsCene上。我如何做到这一点,但我可以添加许多Qpixmap并随意删除它们。我尝试创建一个Qpixmap列表和一个Qgraphicspixmapitem,但是如果我删除或重新排列Qpixmap的顺序,它会变得很混乱。有更好的方法吗C++ Qt将许多QGraphicsPixmapItem添加到QGraphicscene中,c++,qt,qgraphicsscene,qgraphicsitem,qpixmap,C++,Qt,Qgraphicsscene,Qgraphicsitem,Qpixmap,我试图创建一个像大多数照片编辑器程序(Photoshop)一样的图层系统,我基本上使用QGraphicsPixmapItem::setPixmap(QPixmap*图像)绘制一个QGraphicsPixmapItem;在QsCene上。我如何做到这一点,但我可以添加许多Qpixmap并随意删除它们。我尝试创建一个Qpixmap列表和一个Qgraphicspixmapitem,但是如果我删除或重新排列Qpixmap的顺序,它会变得很混乱。有更好的方法吗 QTimer *timer = new QT
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(draw())); //calls the function below to redraw sc
timer->start(30);
这将每30毫秒更新一次Graphicscene,以便绘制我在pixmap*图像上所做的任何绘制,但现在我想获得一个QPixmap列表,并将它们添加到场景everytime draw()调用,但问题是我需要一个QGraphicsPixmapItem列表,如果我删除一个层或移动它们的顺序,我希望关联的QGraphicsPixmapItem也被删除/移动。我想我能做到,但看起来很复杂,有什么建议吗
void PaintArea::draw()
{
m_item->setPixmap(*image); //Do this but call layerManager.getListOfLayers() and add each to the scene
}
下面的小示例应用程序显示了如何继续。基本上,有两个模型和两个视图。模型是QGraphicscene和标准QStandardItemModel,而视图是QListView和QGraphicsView 主要任务是通过使用信号和插槽使两个模型保持同步 可以使用“添加”按钮和关联菜单修改模型。对于这个小应用程序,您只能添加、删除和更改您的pixmap图片。添加其他操作(如通过拖放移动项目)以及使用可检查操作和其他自定义用户角色隐藏/可见项目,都非常简单
#include <QApplication>
#include <QFileDialog>
#include <QGraphicsPixmapItem>
#include <QGraphicsView>
#include <QHBoxLayout>
#include <QListView>
#include <QMenu>
#include <QPushButton>
#include <QStandardItemModel>
int main(int argc, char* argv[]) {
QApplication app(argc, argv);
auto frame = new QFrame;
frame->setLayout(new QHBoxLayout);
auto listView = new QListView;
frame->layout()->addWidget(listView);
auto graphicsView = new QGraphicsView;
frame->layout()->addWidget(graphicsView);
auto graphicsScene = new QGraphicsScene;
graphicsView->setScene(graphicsScene);
auto myModel = new QStandardItemModel;
auto btnAdd = new QPushButton("Add");
frame->layout()->addWidget(btnAdd);
QObject::connect(btnAdd, &QPushButton::clicked, [&]() {
auto item = new QStandardItem("Pixmap");
item->setData(QString("./data/test.png"), Qt::ItemDataRole::UserRole + 1);
myModel->appendRow(item);
});
listView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
QObject::connect(listView, &QListView::customContextMenuRequested, [&](const QPoint& pos) {
auto index = listView->indexAt(pos);
QMenu menu;
auto remove = menu.addAction("Remove", [&]() {
myModel->removeRow(index.row(), index.parent());
});
if (!index.isValid()) remove->setEnabled(false);
auto changeImage = menu.addAction("Change...", [&]() {
auto file=QFileDialog::getOpenFileName(frame, "Select PNG file", "./data/", "(*.png)");
if (file.isEmpty()) return;
myModel->setData(index, file, Qt::ItemDataRole::UserRole + 1);
});
if (!index.isValid()) changeImage->setEnabled(false);
menu.exec(listView->mapToGlobal(pos));
});
QObject::connect(myModel, &QStandardItemModel::dataChanged, [&](const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector<int>& roles = QVector<int>()) {
if (auto item = myModel->itemFromIndex(topLeft)) {
if (auto pixItem = dynamic_cast<QGraphicsPixmapItem*>(graphicsScene->items()[topLeft.row()])) {
pixItem->setPixmap(QPixmap(item->data(Qt::ItemDataRole::UserRole + 1).toString()));
}
}
});
QObject::connect(myModel, &QStandardItemModel::rowsInserted, [&](const QModelIndex& parent, int first, int last) {
for (auto iter = first; iter <= last; iter++) {
auto index=myModel->index(iter, 0, parent);
auto pixmap=myModel->data(index, Qt::ItemDataRole::UserRole + 1).toString();;
auto item=graphicsScene->addPixmap(QPixmap(pixmap));
}
});
QObject::connect(myModel, &QStandardItemModel::rowsRemoved, [&](const QModelIndex& parent, int first, int last) {
auto items = graphicsScene->items();
for (auto iter = first; iter <= last; iter++) {
graphicsScene->removeItem(items[iter]);
}
});
listView->setModel(myModel);
frame->show();
return app.exec();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
int main(int argc,char*argv[]){
QApplication应用程序(argc、argv);
自动车架=新的QFrame;
框架->设置布局(新的QHBoxLayout);
自动列表视图=新的QListView;
框架->布局()->addWidget(listView);
自动图形视图=新的QGraphicsView;
框架->布局()->添加小部件(图形视图);
auto Graphicscene=新的QGraphicscene;
图形视图->设置场景(图形场景);
auto myModel=新的QStandardItemModel;
自动btnAdd=新的QPUSH按钮(“添加”);
框架->布局()->添加小部件(btnAdd);
QObject::connect(b添加,&QPushButton::单击,[&](){
自动项=新的QS标准项(“Pixmap”);
item->setData(QString(“./data/test.png”),Qt::ItemDataRole::UserRole+1);
myModel->appendRow(项目);
});
listView->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
QObject::connect(listView和QListView::customContextMenuRequested,[&](常量QPoint和pos){
自动索引=列表视图->索引(pos);
QMenu菜单;
自动删除=menu.addAction(“删除”、[&](){
myModel->removeRow(index.row(),index.parent());
});
如果(!index.isValid())删除->设置启用(false);
自动更改图像=menu.addAction(“更改…”,[&](){
自动文件=QFileDialog::getOpenFileName(框架,“选择PNG文件”、“/data/”、“(*.PNG)”);
if(file.isEmpty())返回;
myModel->setData(索引、文件、Qt::ItemDataRole::UserRole+1);
});
如果(!index.isValid())changeImage->setEnabled(false);
menu.exec(listView->mapToGlobal(pos));
});
QObject::connect(myModel,&QStandardItemModel::dataChanged,[&](常量QModelIndex&topLeft,常量QModelIndex&bottomRight,常量QVector&roles=QVector()){
如果(自动项目=myModel->itemFromIndex(左上角)){
if(auto pixItem=dynamic_cast(graphicscene->items()[topLeft.row()])){
pixItem->setPixmap(QPixmap(item->data(Qt::ItemDataRole::UserRole+1.toString());
}
}
});
QObject::connect(myModel,&QStandardItemModel::rowsInserted,[&](常量QModelIndex&parent,int first,int last){
用于(自动iter=第一;iter索引(iter,0,父级);
auto-pixmap=myModel->data(索引,Qt::ItemDataRole::UserRole+1);;
自动项=graphicscene->addPixmap(QPixmap(pixmap));
}
});
QObject::connect(myModel,&QStandardItemModel::rowsRemoved,[&](常量QModelIndex&parent,int first,int last){
自动项目=Graphicscene->items();
用于(自动iter=第一;iter移除项目[iter]);
}
});
listView->setModel(myModel);
框架->显示();
返回app.exec();
}
头文件:
...
QGraphicsScene *scene; QGraphicsItemGroup *itemGroup;
...
.cpp文件:
void PaintArea::draw()
{
m_item->setPixmap(*image); m_item->setGroup(itemGroup); // Layers-related code
}
void PaintArea::deleteGroup(QGraphicsItemGroup *group)
{
scene->destroyItemGroup(group); // Layers-related code
}
您是否尝试过使用
QGraphicsSiteMgroup
?如果我正确理解您的问题,您只需将它们分组,并影响整个组的层。无法在5分钟内编辑最后一条注释,因此就是这样。请使用QGraphicscenScene::destroyItemGroup
删除该组。请在I上使用QGraphicsSitem::setPos
tem组作为一个整体进行集体移动。(记住QGraphicsSiteMgroup继承了QGraphicsItem)啊,好的,谢谢你,我不知道这是一件事,我会在每次抽签呼叫时销毁组吗?@jameskerr抱歉延迟响应。不,如果你想同时删除/删除所有组,你会销毁组。