Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/160.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Qt将许多QGraphicsPixmapItem添加到QGraphicscene中_C++_Qt_Qgraphicsscene_Qgraphicsitem_Qpixmap - Fatal编程技术网

C++ Qt将许多QGraphicsPixmapItem添加到QGraphicscene中

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

我试图创建一个像大多数照片编辑器程序(Photoshop)一样的图层系统,我基本上使用QGraphicsPixmapItem::setPixmap(QPixmap*图像)绘制一个QGraphicsPixmapItem;在QsCene上。我如何做到这一点,但我可以添加许多Qpixmap并随意删除它们。我尝试创建一个Qpixmap列表和一个Qgraphicspixmapitem,但是如果我删除或重新排列Qpixmap的顺序,它会变得很混乱。有更好的方法吗

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抱歉延迟响应。不,如果你想同时删除/删除所有组,你会销毁组。