IStyleGallery.AddItem、UpdateItem、RemoveItem用法 (转载)

解决使用ArcEngine进行符号库管理时遇到的错误,通过正确设置IStyleGalleryStorage接口的TargetFile属性来避免调用AddItem、UpdateItem和RemoveItem方法时报错。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

天做arcengine的符号库管理,做好了符号文件symbol.StyleServer。用到方法AddItem、UpdateItem、RemoveItem。怎么都报错。网上同样问题的人也有一些,就是不见人回答,只有自己琢磨。最终搞定了。写下来,备用。

  参考了一篇这样的文章IStyleGallery 和IstyleGalleryItem以及IStyleGalleryStorage接口理解.

注意:用AddItem、UpdateItem、RemoveItem之前,必须用到IStyleGalleryStorage接口的TargetFile属性。如果没有设置这个属性,就会报错,错误信息如下:

对 COM 组件的调用返回了错误 HRESULT E_FAIL。” 错误代码:“-2147467259”

读取ServerStyle文件代码如下:

        private string styleName = "3D Basic.ServerStyle";
        public void ReadStyleServer()
        {
            IStyleGallery tStyleGallery = new ServerStyleGalleryClass(); IStyleGalleryStorage tStyleGalleryStorage = tStyleGallery as IStyleGalleryStorage; tStyleGalleryStorage.AddFile(styleName); // tStyleGalleryStorage.TargetFile = styleName_TargetFile; IEnumStyleGalleryItem tStyleGalleryItems = tStyleGallery.get_Items("Marker Symbols", styleName, ""); tStyleGalleryItems.Reset(); IStyleGalleryItem tStyleGalleryItem = tStyleGalleryItems.Next(); int tIndex = 0; try { while (tStyleGalleryItem != null) { string tName = tStyleGalleryItem.Name; tStyleGalleryItem.Name = tName + tIndex; tIndex++; tStyleGallery.UpdateItem(tStyleGalleryItem);//这个地方报错 
                    tStyleGalleryItem = tStyleGalleryItems.Next();
                }
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                string tErrorMessage = ex.Message +
                    ex.ErrorCode;
            }
            finally
            {
                //释放这个接口,不然再次读取时会报错
                  ReleaseCom(tStyleGalleryItems);
                ReleaseCom(tStyleGallery);
            }
        }
        private void ReleaseCom(object o) { while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) { } }

要想更新,必须用到TargetFile属性。具体为什么必须用这个,原因不明,可能是文件独占。所以只能走一个弯。思路如下:

(1)先把"3D Basic.ServerStyle"备份一个临时文件,备份的文件名称"Temp.ServerStyle"

(2)设置TargetFile,使其指向"Temp.ServerStyle"

(3)开始更新,更新完毕后,拷贝"Temp.ServerStyle"覆盖原来的"3D Basic.ServerStyle"

代码如下(只写数据跟新,不写文件拷贝和覆盖)

        private string styleName_TargetFile = "Temp.ServerStyle";
        private string styleName = "3D Basic.ServerStyle"; public void ReadStyleServer() { IStyleGallery tStyleGallery = new ServerStyleGalleryClass(); IStyleGalleryStorage tStyleGalleryStorage = tStyleGallery as IStyleGalleryStorage; tStyleGalleryStorage.AddFile(styleName); tStyleGalleryStorage.TargetFile = styleName_TargetFile; IEnumStyleGalleryItem tStyleGalleryItems = tStyleGallery.get_Items("Marker Symbols", styleName, ""); tStyleGalleryItems.Reset(); IStyleGalleryItem tStyleGalleryItem = tStyleGalleryItems.Next(); int tIndex = 0; try { while (tStyleGalleryItem != null) { string tName = tStyleGalleryItem.Name; tStyleGalleryItem.Name = tName + tIndex; tIndex++; tStyleGallery.UpdateItem(tStyleGalleryItem); tStyleGalleryItem = tStyleGalleryItems.Next(); } } catch (System.Runtime.InteropServices.COMException ex) { string tErrorMessage = ex.Message + ex.ErrorCode; } finally { //释放这个接口,不然再次读取时会报错 ReleaseCom(tStyleGalleryItems); ReleaseCom(tStyleGallery); } } private void ReleaseCom(object o) { while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) { } }
不再报错,顺利运行。AddItem、RemoveItem方法类似。AddItem的时候,如果目标文件不存在,接口会自动创建目标文件。
作者: cglnet
本文版权归cglNet和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class InventoryManager : MonoBehaviour { public GameObject inventoryUI; public GameObject itemSlotPrefab; public Transform itemSlotContainer; public List<Item> items = new List<Item>(); public Dictionary<string, int> itemCounts = new Dictionary<string, int>(); private bool isInventoryOpen = false; using UnityEngine; [CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")] public class Item : ScriptableObject { public new string name; public string description; public Sprite icon; } private void Start() { inventoryUI.SetActive(false); } private void Update() { if (Input.GetKeyDown(KeyCode.I)) { ToggleInventory(); } } public void AddItem(Item item) { items.Add(item); if (itemCounts.ContainsKey(item.name)) { itemCounts[item.name]++; } else { itemCounts[item.name] = 1; CreateItemSlot(item); } UpdateItemSlot(item); } public void RemoveItem(Item item) { items.Remove(item); if (itemCounts.ContainsKey(item.name)) { itemCounts[item.name]--; if (itemCounts[item.name] == 0) { itemCounts.Remove(item.name); DestroyItemSlot(item); } } UpdateItemSlot(item); } public void UpdateItemCount(Item item) { if (itemCounts.ContainsKey(item.name)) { itemCounts[item.name]--; UpdateItemSlot(item); } } public void ToggleInventory() { isInventoryOpen = !isInventoryOpen; inventoryUI.SetActive(isInventoryOpen); } private void CreateItemSlot(Item item) { GameObject itemSlot = Instantiate(itemSlotPrefab, itemSlotContainer); itemSlot.name = item.name; itemSlot.GetComponent<Image>().sprite = item.icon; } private void DestroyItemSlot(Item item) { Transform itemSlot = itemSlotContainer.Find(item.name); Destroy(itemSlot.gameObject); } private void UpdateItemSlot(Item item) { Transform itemSlot = itemSlotContainer.Find(item.name); Text itemText = itemSlot.GetComponentInChildren<Text>(); itemText.text = itemCounts[item.name].ToString(); } }
06-10
// 购物车项 const [items, setItems] = useState<selectResultData[]>([]); const addItem = async (item2: selectResultData) => { // const itemsIndex = items.findIndex((i) => i.id === item2.id); const itemsIndex = items.findIndex( (i) => i.id === item2.id && _.isEqual(i.selectExt, item2.selectExt) ); console.log({ itemsIndex }, "itemsIndexitemsIndex"); if (itemsIndex < 0) { setMoadlB(false); if (!item2.selectSum) { const selectSellPrice = item2?.customAttr.find( (item) => item.key === "sellPrice" )?.value; setItems([...items, { ...item2, num: 1, selectSum: selectSellPrice }]); upt([...items, { ...item2, num: 1, selectSum: selectSellPrice }]); } else { setItems([...items, { ...item2, num: 1 }]); upt([...items, { ...item2, num: 1 }]); } } else { const updateItems = [...items]; // 更新 index 对应的元素 updateItems[itemsIndex] = { ...updateItems[itemsIndex], num: updateItems[itemsIndex].num + 1, }; setItems(updateItems); upt(updateItems); } }; const removeItem = async (item2: selectResultData) => { // const updateCarts = [...cartItems]; const itemsIndex = items.findIndex( (i) => i.id === item2.id && _.isEqual(i.selectExt, item2.selectExt) ); if (itemsIndex >= 0) { const updateItems = [...items]; // 是否存在相同id和ext属性的商品,存在则num-1 if (updateItems[itemsIndex].num > 1) { updateItems[itemsIndex] = { ...updateItems[itemsIndex], num: updateItems[itemsIndex].num - 1, }; } else { // 数组中删除该商品 updateItems.splice(itemsIndex, 1); } setItems(updateItems); // upt(updateItems); } }; 上面是添加和减少购物车的方法,我在进行添加购物车操作时,怎么把门店id作为key,购物车数据作为value存储到一个usestate并设置usestate初始值为空数组?如果减少购物车时,怎么把对应的门店id的value中的商品减少?如果是多家门店购物车,请新增一个对象在去存储另一家店购物车的数据到同一个usestate中,并将处理好的数据存到全局变量redux中类似dispath(putShopCar(数据)),能实现吗
06-05
import os import sys import numpy as np from PyQt5.QtWidgets import (QGraphicsView, QGraphicsScene, QGraphicsPixmapItem, QRubberBand, QApplication, QGraphicsPathItem, QMenu) from PyQt5.QtGui import (QPixmap, QImage, QPainter, QPen, QColor, QBrush, QKeyEvent, QTransform, QPainterPath, QCursor, QPolygonF) from PyQt5.QtCore import (Qt, QPoint, QRect, QSize, QEvent, QPointF, QRectF, pyqtSignal, QTimer, QLineF, QVariantAnimation) class ImageCanvas(QGraphicsView): # 信号定义 zoom_changed = pyqtSignal(float) image_changed = pyqtSignal(QImage) mouse_position_changed = pyqtSignal(QPointF, str) selection_changed = pyqtSignal(QRectF) tool_changed = pyqtSignal(int) # 工具枚举 TOOL_SELECT = 0 TOOL_CROP = 1 TOOL_BRUSH = 2 TOOL_SHAPE = 3 TOOL_TEXT = 4 TOOL_ERASER = 5 def __init__(self, parent=None): super().__init__(parent) self.parent_window = parent self.setRenderHint(QPainter.Antialiasing) self.setRenderHint(QPainter.SmoothPixmapTransform) self.setDragMode(QGraphicsView.ScrollHandDrag) self.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) self.setResizeAnchor(QGraphicsView.AnchorUnderMouse) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setInteractive(True) self.viewport().setCursor(Qt.CrossCursor) # 创建场景 self.scene = QGraphicsScene(self) self.setScene(self.scene) self.scene.setBackgroundBrush(QBrush(QColor(50, 50, 50))) # 初始化变量 self.zoom_factor = 1.0 self.min_zoom = 0.05 self.max_zoom = 50.0 self.original_image = QImage() self.displayed_image = QImage() self.current_image_item = None self.saved_transforms = None # 工具相关状态 self.rubber_band = QRubberBand(QRubberBand.Rectangle, self.viewport()) self.rubber_band.hide() self.selection_rect = QRectF() self.selection_active = False self.selection_start = QPointF() # 当前工具状态 self.current_tool = self.TOOL_SELECT self.tool_settings = { 'brush_size': 5, 'brush_color': QColor(255, 0, 0, 255), 'eraser_size': 20, 'shape_type': 0, # 0:矩形, 1:圆形, 2:直线 'antialias': True, 'opacity': 1.0 } # 绘制相关状态 self.drawing_active = False self.drawing_path = None self.drawing_item = None self.drawing_start = QPointF() self.current_layer = 0 self.layers = [] # 初始化默认图层 self.add_new_layer("Background", QColor(255, 255, 255)) # 历史记录快照 self.snapshots = [] self.current_snapshot = -1 # 安装事件过滤器 self.viewport().installEventFilter(self) # 状态提示定时器 self.status_timer = QTimer(self) self.status_timer.setSingleShot(True) self.status_timer.timeout.connect(self._clear_status) # ==================== 图层管理功能 ==================== def add_new_layer(self, name, fill_color=QColor(0, 0, 0, 0)): """添加新图层""" layer = { 'name': name, 'visible': True, 'locked': False, 'opacity': 1.0, 'image': QImage(self.displayed_image.size(), QImage.Format_ARGB32), 'item': None } layer['image'].fill(fill_color) self.layers.append(layer) self.current_layer = len(self.layers) - 1 self._render_layers() return self.current_layer def remove_layer(self, index): """移除指定图层""" if 0 <= index < len(self.layers): if self.layers[index]['item']: self.scene.removeItem(self.layers[index]['item']) del self.layers[index] if index <= self.current_layer: self.current_layer = max(0, self.current_layer - 1) self._render_layers() def set_current_layer(self, index): """设置当前活动图层""" if 0 <= index < len(self.layers): self.current_layer = index return True return False def toggle_layer_visibility(self, index): """切换图层可见性""" if 0 <= index < len(self.layers): self.layers[index]['visible'] = not self.layers[index]['visible'] self._render_layers() def _render_layers(self): """渲染所有可见图层到显示图像""" if not self.layers: return # 创建一个临时图像来合成所有图层 size = self.displayed_image.size() composite = QImage(size, QImage.Format_ARGB32) composite.fill(Qt.transparent) painter = QPainter(composite) for layer in self.layers: if not layer['visible']: continue painter.setOpacity(layer['opacity']) painter.drawImage(0, 0, layer['image']) painter.end() # 更新显示 self.displayed_image = composite self._show_image(composite) # 更新UI self.image_changed.emit(self.displayed_image) # ==================== 图像管理功能 ==================== def set_image(self, image): """设置要显示的图像""" if image.isNull(): self.clear() return self.original_image = image.copy() self.displayed_image = image.copy() self._clear_layers() self.add_new_layer("Background", Qt.white) self.layers[0]['image'] = image.copy() self.reset_view() self.image_changed.emit(self.displayed_image) self.take_snapshot() def update_image(self): """更新显示的图像""" if not self.displayed_image.isNull(): self._show_image(self.displayed_image) self.image_changed.emit(self.displayed_image) def clear(self): """清除画布""" self.scene.clear() self.current_image_item = None self.displayed_image = QImage() self.original_image = QImage() self.zoom_factor = 1.0 self.zoom_changed.emit(self.zoom_factor) self.resetTransform() self._clear_layers() def reset_view(self): """重置视图到初始状态""" if not self.displayed_image.isNull(): self._show_image(self.displayed_image) self.fit_to_view() def get_current_image(self): """获取当前显示的图像""" return self.displayed_image def get_original_image(self): """获取原始未编辑图像""" return self.original_image def get_pixel_at(self, pos): """获取指定位置的像素颜色""" if self.displayed_image.isNull(): return None if not self.current_image_item: return None # 转换到图像坐标 img_pos = self.map_to_image(pos) x = int(img_pos.x()) y = int(img_pos.y()) # 检查边界 if 0 <= x < self.displayed_image.width() and 0 <= y < self.displayed_image.height(): color = QColor(self.displayed_image.pixel(x, y)) return color return None def map_to_image(self, scene_pos): """将场景坐标映射到图像坐标""" if not self.current_image_item: return QPointF() return self.current_image_item.mapFromScene(scene_pos) # ==================== 缩放功能 ==================== def zoom_in(self): """放大图像""" self.set_zoom(self.zoom_factor * 1.2) def zoom_out(self): """缩小图像""" self.set_zoom(self.zoom_factor * 0.8) def fit_to_view(self): """适应窗口大小""" if self.current_image_item: self.fitInView(self.scene.itemsBoundingRect(), Qt.KeepAspectRatio) self._update_zoom_factor() def set_zoom(self, factor): """设置特定缩放级别""" factor = max(self.min_zoom, min(factor, self.max_zoom)) if abs(factor - self.zoom_factor) > 0.01: self.zoom_factor = factor self.resetTransform() self.scale(factor, factor) self.zoom_changed.emit(self.zoom_factor * 100) def _update_zoom_factor(self): """更新缩放因子""" view_rect = self.transform().mapRect(QRectF(0, 0, 1, 1)) self.zoom_factor = 1.0 / view_rect.width() self.zoom_changed.emit(self.zoom_factor * 100) # ==================== 工具控制功能 ==================== def set_tool(self, tool_id): """设置当前工具""" self.current_tool = tool_id self.tool_changed.emit(tool_id) self._update_cursor() def set_tool_setting(self, key, value): """设置工具参数""" if key in self.tool_settings: self.tool_settings[key] = value self._update_cursor() def _update_cursor(self): """根据当前工具更新光标""" if self.current_tool == self.TOOL_SELECT: self.viewport().setCursor(Qt.CrossCursor) elif self.current_tool == self.TOOL_CROP: self.viewport().setCursor(Qt.CrossCursor) elif self.current_tool == self.TOOL_BRUSH: # 创建画笔形状的光标 size = self.tool_settings['brush_size'] * self.zoom_factor size = max(6, min(int(size), 100)) pixmap = QPixmap(size, size) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) painter.setPen(QPen(Qt.black, 1)) painter.setBrush(QBrush(self.tool_settings['brush_color'])) painter.drawEllipse(1, 1, size - 2, size - 2) painter.end() self.viewport().setCursor(QCursor(pixmap, size / 2, size / 2)) elif self.current_tool == self.TOOL_ERASER: # 创建橡皮擦形状的光标 size = self.tool_settings['eraser_size'] * self.zoom_factor size = max(6, min(int(size), 100)) pixmap = QPixmap(size, size) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) painter.setPen(QPen(Qt.black, 1)) painter.setBrush(QBrush(Qt.white)) painter.drawRect(1, 1, size - 2, size - 2) painter.end() self.viewport().setCursor(QCursor(pixmap, size / 2, size / 2)) elif self.current_tool in [self.TOOL_SHAPE, self.TOOL_TEXT]: self.viewport().setCursor(Qt.CrossCursor) # ==================== 历史记录功能 ==================== def take_snapshot(self): """创建当前状态的快照""" # 只保留最近的20个快照 if self.current_snapshot < len(self.snapshots) - 1: self.snapshots = self.snapshots[:self.current_snapshot + 1] # 保存图层状态 snapshot = { 'layers': [], 'current_layer': self.current_layer } for layer in self.layers: snapshot['layers'].append({ 'image': layer['image'].copy(), 'visible': layer['visible'], 'opacity': layer['opacity'] }) self.snapshots.append(snapshot) self.current_snapshot = len(self.snapshots) - 1 return True def restore_snapshot(self, index=None): """恢复指定快照""" if index is None: index = self.current_snapshot if 0 <= index < len(self.snapshots): snapshot = self.snapshots[index] # 恢复图层状态 self.layers = [] for layer_data in snapshot['layers']: self.layers.append({ 'image': layer_data['image'].copy(), 'visible': layer_data['visible'], 'opacity': layer_data['opacity'], 'locked': False, 'name': f"Layer {len(self.layers)}", 'item': None }) self.current_layer = snapshot['current_layer'] self._render_layers() self.current_snapshot = index return True return False def undo(self): """撤销上一步操作""" if self.current_snapshot > 0: self.restore_snapshot(self.current_snapshot - 1) return True return False def redo(self): """重做上一步操作""" if self.current_snapshot < len(self.snapshots) - 1: self.restore_snapshot(self.current_snapshot + 1) return True return False # ==================== 绘图功能 ==================== def start_drawing(self, scene_pos): """开始绘图操作""" if self.current_tool in [self.TOOL_BRUSH, self.TOOL_ERASER]: self.drawing_active = True self.drawing_start = scene_pos self.drawing_path = QPainterPath() self.drawing_path.moveTo(self.map_to_image(scene_pos)) if self.current_tool == self.TOOL_BRUSH: pen = QPen(self.tool_settings['brush_color'], self.tool_settings['brush_size']) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) else: # 橡皮擦 pen = QPen(QColor(255, 255, 255, 255), self.tool_settings['eraser_size']) pen.setCapStyle(Qt.RoundCap) if self.tool_settings['antialias']: pen.setCosmetic(True) self.drawing_item = QGraphicsPathItem() self.drawing_item.setPen(pen) self.drawing_item.setPath(self.drawing_path) self.drawing_item.setOpacity(self.tool_settings['opacity']) self.scene.addItem(self.drawing_item) elif self.current_tool == self.TOOL_SHAPE: self.drawing_active = True self.drawing_start = scene_pos self.drawing_item = self._create_shape(scene_pos, scene_pos) if self.drawing_item: self.scene.addItem(self.drawing_item) elif self.current_tool == self.TOOL_TEXT: # 文本输入通过专用方法处理 pass def continue_drawing(self, scene_pos): """继续绘图操作""" if not self.drawing_active: return if self.current_tool in [self.TOOL_BRUSH, self.TOOL_ERASER]: # 添加路径点 new_point = self.map_to_image(scene_pos) self.drawing_path.lineTo(new_point) self.drawing_item.setPath(self.drawing_path) elif self.current_tool == self.TOOL_SHAPE: # 更新形状 if self.drawing_item: self.scene.removeItem(self.drawing_item) self.drawing_item = self._create_shape(self.drawing_start, scene_pos) if self.drawing_item: self.scene.addItem(self.drawing_item) def stop_drawing(self): """完成绘图操作并应用到图层""" if not self.drawing_active: return if self.drawing_item: # 创建绘制到图层的画家 painter = QPainter(self.layers[self.current_layer]['image']) painter.setRenderHint(QPainter.Antialiasing, self.tool_settings['antialias']) painter.setCompositionMode(QPainter.CompositionMode_SourceOver) painter.setOpacity(self.tool_settings['opacity']) # 从绘图项获取路径 path = self.drawing_item.path() # 根据工具应用不同绘制 if self.current_tool == self.TOOL_BRUSH: painter.setPen(QPen( self.tool_settings['brush_color'], self.tool_settings['brush_size'], Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin )) painter.setBrush(Qt.NoBrush) painter.drawPath(path) elif self.current_tool == self.TOOL_ERASER: # 使用橡皮擦 painter.setCompositionMode(QPainter.CompositionMode_Clear) painter.setPen(QPen( Qt.transparent, self.tool_settings['eraser_size'], Qt.SolidLine, Qt.RoundCap )) painter.drawPath(path) 这个代码吗给全
06-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值