不贪三更色,不恋一更食

俗语本来就是从民间流传下来的,任何时代的人们都非常聪明,把那些自己总结的道理,用俗语形式教给后人,因为贴近人们的生活,因此俗语虽然没有诗的意境,却蕴含了很多道理,大到人们修身立世,小到老百姓的衣食住行。

俗语“不贪三更色,不恋一更食”,古人轻易能做到,现代人却很难

诗不是所有人能看懂的,但俗语却是人人都懂。曾经的俗语,一般离不开社会环境的,所以很多关于社会风俗的俗语,过了那个时期就不再被使用。

但这只是一部分而已,比如就有“不贪三更色,不恋一更食”。虽然这句话是老祖宗总结出来的,但是放在当今社会也没什么不妥。

俗语“不贪三更色,不恋一更食”,古人轻易能做到,现代人却很难

我们先说说前半句,那么古代三更是我们现在什么时间呢?换算成现在的时间,就是23:00~1:00。晚上睡太晚了是不好的,不知道现在人们怎么定义晚睡的,但在曾经时代,过了晚上十一点就是晚睡了。

若我们在这时候贪恋美色,晚上休息时间自然不够,直接影响第二天的状态,不仅影响第二天做事,还会对身体造成伤害。都觉得在十一点前进入睡眠较好,看看各大学校的作息时间,一般都会是在十一点熄灯。

而一般的专家学者们给的建议也都是晚上十一点前入睡是对身体比较好的。从这里我们也可以看出,老祖宗们还是把自己身体看的很重要的。

俗语“不贪三更色,不恋一更食”,古人轻易能做到,现代人却很难

那下半句呢?下午七点之后不再进食,因为正常吃晚饭的时间是在五点半,在以前的时代,天黑了人们一般就不会出去了,毕竟当时社会不如我们现在,因此吃了饭没什么事就只能睡觉了。

但是我们现在,由于很多人工作压力较大,因此吃饭时间很不规律,还有人因为工作时间长,晚上需要加餐,因此老祖宗这句俗语很多人是做不到的。

俗语“不贪三更色,不恋一更食”,古人轻易能做到,现代人却很难

虽然我们无法做到,却不是说此话没有道理,因为老祖宗说的这话,除了和当时的社会有关以外,还和我们身体息息相关。

胃的功能不是我们想象的那么强大,很多人晚上加餐,就容易给胃造成不必要的负担,久而久之我们的胃自然就承受不了,因此引发胃病,因此夜宵还是要少吃为好。

俗语“不贪三更色,不恋一更食”,古人轻易能做到,现代人却很难

在我们当今社会,由于社会的发展,很多人的作息都不规律,想要做到老祖宗们所说的,简直难上加难。

明明大家都知道这样是在伤害自己身体,却依旧一意孤行,因此人的健康状况是非常堪忧的,所以我们还是要记住,不管工作多么忙碌,身体才是最重要的。

<think>我们讨论的是如何为组QGraphicsItem设置个显示区域(即裁剪区域),超出该区域的部分显示。在Qt的图形视图框架中,可以通过以下几种方式实现: 1. **为每个QGraphicsItem设置裁剪路径(Clip Path)**:通过重写QGraphicsItem的paint()函数,使用QPainter的setClipPath()来限制绘制区域。但这种方法需要为每个图元单独设置,且当图元有变换时需要注意裁剪路径的变换。 2. **在QGraphicsView的视口上设置裁剪区域**:这种方法是在视口(viewport)上设置个统的裁剪区域,所有图元在绘制到视口之前都会被这个区域裁剪。这种方法简单且高效,适用于整个视图的裁剪。 3. **使用QGraphicsItemGroup**:将组图元添加到个QGraphicsItemGroup中,然后为该组设置个裁剪区域。但是,QGraphicsItemGroup本身并没有提供直接的裁剪设置,因此需要重写该组的paint函数或者使用代理项(如QGraphicsProxyWidget)来实现。 4. **使用QGraphicsScene的绘制事件**:重写QGraphicsScene的drawBackground()或drawForeground()来设置整个场景的裁剪区域,但这种方法可能够灵活。 根据引用[1]中提到的,用户想要实现只显示固定区域的功能,并且提到QGraphicsItem没有直接的设置接口。在引用[1]中用户自己摸索出了方法,但没有具体说明。结合引用[5]中提到的,可以通过自定义图元类来实现,即继承QGraphicsItem并重写paint函数,在绘制时设置裁剪区域。 下面我将重点介绍两种常用且有效的方法: ### 方法:在QGraphicsView的视口上设置裁剪区域(推荐) 这种方法适用于整个视图的裁剪,即所有图元都使用同个裁剪区域。步骤如下: 1. 创建个QPainterPath,定义裁剪区域的形状(例如矩形、圆形等)。 2. 在QGraphicsView的视口(viewport)上设置裁剪路径。 示例代码: ```cpp // 创建视图 QGraphicsView *view = new QGraphicsView(scene); // 创建裁剪区域(例如个矩形) QPainterPath clipPath; clipPath.addRect(QRectF(50, 50, 200, 100)); // 定义裁剪区域为场景坐标中的矩形 // 将裁剪区域设置到视口 QRegion clipRegion = QRegion(clipPath.toFillPolygon().toPolygon()); view->viewport()->setClipRegion(clipRegion); ``` 注意:这里设置的裁剪区域是在视图的坐标系中,但上面代码中我们使用的是场景坐标。因此,需要将场景坐标转换为视口坐标。或者,我们可以将裁剪路径定义在视口坐标系中(例如,固定为视口中心的个矩形)。 如果希望裁剪区域随场景起变换(例如视图缩放、平移时裁剪区域也相应变化),则需要在每次视图变换时新裁剪区域。但这样可能会影响性能。 另种做法是:将裁剪路径定义在场景坐标中,然后在绘制前将场景坐标转换为视口坐标。但setClipRegion要求的是视口坐标,所以我们需要在每次视图变换后重新计算。 我们可以连接视图的`transformChanged`信号,在变换发生时新裁剪区域: ```cpp connect(view, &QGraphicsView::transformChanged, [view, clipPath]() { // 将场景坐标的裁剪路径转换为视口坐标 QTransform viewTransform = view->viewportTransform(); QPolygonF viewportPolygon = viewTransform.map(clipPath).toFillPolygon(); QRegion clipRegion = QRegion(viewportPolygon.toPolygon()); view->viewport()->setClipRegion(clipRegion); }); ``` ### 方法二:为每个图元设置裁剪(自定义图元) 如果需要对同的图元组设置同的裁剪区域,那么可以为每个图元单独设置裁剪。这需要自定义QGraphicsItem,重写其paint函数。 步骤: 1. 创建个继承自QGraphicsItem的自定义类。 2. 在该类中定义个裁剪路径(QPainterPath)成员变量,并提供设置方法。 3. 在paint函数中,使用QPainter的setClipPath设置裁剪路径,然后调用基类的绘制。 示例代码: ```cpp class CustomGraphicsItem : public QGraphicsItem { public: void setClipPath(const QPainterPath &path) { m_clipPath = path; update(); } QRectF boundingRect() const override { // 返回图元的边界矩形 return ...; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { // 设置裁剪 painter->setClipPath(m_clipPath, Qt::IntersectClip); // 进行绘制 ... } private: QPainterPath m_clipPath; }; ``` 然后,在创建图元时,设置裁剪路径: ```cpp CustomGraphicsItem *item = new CustomGraphicsItem; QPainterPath clipPath; clipPath.addRect(QRectF(0, 0, 100, 100)); // 相对于图元自身坐标系的裁剪区域 item->setClipPath(clipPath); scene->addItem(item); ``` 注意:裁剪路径的坐标是相对于图元自身的坐标系。如果图元有位置偏移或变换,需要额外考虑。 ### 方法:使用QGraphicsItemGroup并重绘 另种思路是将组图元放入个QGraphicsItemGroup中,然后为这个组设置裁剪。但是,QGraphicsItemGroup本身没有提供裁剪功能。我们可以创建个自定义的组图元,它继承自QGraphicsItemGroup,并重写paint函数,在绘制组之前设置裁剪。 示例: ```cpp class CustomGraphicsItemGroup : public QGraphicsItemGroup { public: void setClipPath(const QPainterPath &path) { m_clipPath = path; prepareGeometryChange(); } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override { painter->save(); painter->setClipPath(m_clipPath, Qt::IntersectClip); QGraphicsItemGroup::paint(painter, option, widget); painter->restore(); } private: QPainterPath m_clipPath; }; ``` 然后,将图元添加到这个组中: ```cpp CustomGraphicsItemGroup *group = new CustomGraphicsItemGroup; scene->addItem(group); // 添加图元到组 group->addToGroup(item1); group->addToGroup(item2); // 设置组的裁剪区域(在组的局部坐标系中) QPainterPath clipPath; clipPath.addRect(QRectF(0,0,100,100)); group->setClipPath(clipPath); ``` ### 总结 - 如果整个视图需要同个裁剪区域,推荐使用**方法**(在视口上设置裁剪),简单高效。 - 如果需要对同的图元组设置同的裁剪区域,则可以使用**方法二**(自定义图元)或**方法**(自定义组)。其中方法适用于组图元共享同个裁剪区域的情况。 ### 注意事项 1. **性能考虑**:裁剪操作会增加绘制开销,尤其是在裁剪区域复杂且图元数量多的情况下。 2. **坐标系统**:在设置裁剪路径时,定要注意坐标系统。裁剪路径的坐标系必须与绘制时使用的坐标系致(场景坐标、视图坐标或图元局部坐标)。 3. **变换**:如果图元或视图有变换(如缩放、旋转),裁剪路径也会随之变换。如果希望裁剪区域固定变,则需要做相应的坐标转换。 以上方法均可实现图元区域的裁剪,请根据实际需求选择合适的方式。 ### 相关问题 1. 如何动态调整裁剪区域? 2. 在QGraphicsView中如何实现规则形状的裁剪? 3. 裁剪区域能否支持动画效果? 4. 如何取消已经设置的裁剪区域?</think>### 在Qt中为QGraphicsItem组设置显示区域的方法 要为QGraphicsItem组设置显示边界(超出区域显示),可通过以下种核心方法实现: #### 方法:使用视口裁剪(推荐) **原理**:在QGraphicsView的视口(viewport)上设置裁剪区域 ```cpp // 创建裁剪区域(矩形示例) QPainterPath clipPath; clipPath.addRect(100, 100, 300, 200); // (x,y,w,h) // 将路径转换为区域并应用到视口 QRegion clipRegion = QRegion(clipPath.toFillPolygon().toPolygon()); graphicsView->viewport()->setClipRegion(clipRegion); // 可选:设置渲染提示优化显示 graphicsView->setRenderHint(QPainter::Antialiasing); ``` **特点**: - 所有图元共享同裁剪区域 - 高性能,适合大量图元[^1] - 区域坐标基于视图坐标系 #### 方法二:自定义图元裁剪 **原理**:继承QGraphicsItem并重写paint()方法 ```cpp class ClippedItem : public QGraphicsItem { public: void setClipRegion(const QPainterPath &path) { m_clipPath = path; update(); } void paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) override { painter->setClipPath(m_clipPath); // 关键裁剪指令 // 正常绘制图元内容... painter->drawRect(boundingRect()); } QRectF boundingRect() const override { return QRectF(0,0,100,100); } private: QPainterPath m_clipPath; }; // 使用示例 ClippedItem *item = new ClippedItem; item->setClipRegion(QPainterPath().addEllipse(0,0,50,50)); // 圆形裁剪 scene->addItem(item); ``` **适用场景**: - 同图元需要同裁剪形状 - 需要动态修改裁剪区域[^5] #### 方法:场景层裁剪 **原理**:使用QGraphicsItemGroup作为容器层 ```cpp // 创建容器组 QGraphicsItemGroup *group = new QGraphicsItemGroup; // 添加裁剪蒙版(关键步骤) QGraphicsPathItem *mask = new QGraphicsPathItem; mask->setPath(QPainterPath().addRoundedRect(0,0,200,150,10,10)); mask->setBrush(Qt::white); mask->setZValue(1); // 置于顶层 // 设置组合裁剪 group->setHandlesChildEvents(false); // 允许穿透事件 group->setFiltersChildEvents(true); // 启用裁剪 // 添加图元到组 group->addToGroup(item1); group->addToGroup(item2); group->addToGroup(mask); // 蒙版必须最后添加 // 设置组的显示属性 group->setFlag(QGraphicsItem::ItemClipsChildrenToShape); // 关键属性 scene->addItem(group); ``` **优势**: - 整组图元统裁剪 - 支持复杂形状(圆角矩形、多边形等) - 保持图元交互能力[^4] ### 关键参数说明 | **参数** | **类型** | **作用** | **示例值** | |----------|----------|----------|------------| | `setClipPath()` | QPainterPath | 定义裁剪形状 | `addEllipse(0,0,100,100)` | | `ItemClipsChildrenToShape` | ItemFlag | 启用子项裁剪 | `setFlag(QGraphicsItem::ItemClipsChildrenToShape)` | | `setClipRegion()` | QRegion | 设置像素精确区域 | `QRegion(QRect(10,10,50,50))` | | `setFiltersChildEvents` | bool | 控制子项事件穿透 | `group->setFiltersChildEvents(true)` | ### 动态调整技巧 ```cpp // 响应窗口大小变化 void MainWindow::resizeEvent(QResizeEvent*) { QRect visibleArea = view->rect(); QPainterPath newPath; newPath.addRect(visibleArea.adjusted(20,20,-20,-20)); // 新所有组内图元 for(QGraphicsItem *item : clipGroup->childItems()) { if(ClippedItem *c = qgraphicsitem_cast<ClippedItem*>(item)) c->setClipRegion(newPath); } } ``` ### 性能优化建议 1. **区域简化**:复杂路径先用`QPainterPath::simplified()`优化 2. **缓存绘制**:对静态内容启用`QGraphicsItem::ItemCoordinateCache` 3. **分层管理**:频繁变化的图元放在独立层 4. **区域合并**:多个相邻图元使用相同裁剪路径[^1] > **重要提示**:当使用`QGraphicsView::scale()`缩放视图时,需同步新裁剪区域: > ```cpp > // 计算缩放后的有效区域 > QTransform t = view->transform().inverted(); > QRectF scaledRect = t.mapRect(originalRect); > ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值