qt 6.7 创建一个矩形,默认为红色;当鼠在这个矩形内点击的时候,设置个矩形为选中状态,再次点击取消选中状态,恢复原来的边线颜色;选中状态的矩形边线闪烁;闪烁的方式是颜色红蓝交替

Qt 6.7绘制矩形及相关功能实现

要在Qt 6.7中实现这个功能,你可以使用QGraphicsViewQGraphicsScene来显示一个矩形,并使用QTimer来实现边线的闪烁效果。以下是一个基本的实现步骤和代码示例:

  1. 创建一个自定义的QGraphicsItem来表示矩形:这个自定义的QGraphicsItem将处理鼠标点击事件,并根据点击次数来切换选中状态。
  2. 使用QGraphicsScene来添加和管理这个矩形QGraphicsScene提供了一个用于管理和渲染图形项的场景。
  3. 使用QGraphicsView来显示QGraphicsSceneQGraphicsView提供了一个可视化的界面来展示场景中的图形项。
  4. 使用QTimer来实现边线的闪烁效果:当矩形被选中时,可以使用QTimer来定时切换边线颜色,从而实现闪烁效果。

以下是一个简化的代码示例,展示了如何实现这个功能:


#include <QApplication>  
#include <QGraphicsView>  
#include <QGraphicsScene>  
#include <QGraphicsRectItem>  
#include <QTimer>  
#include <QMouseEvent>  
  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem() {  
        setRect(0, 0, 100, 100);  
        setPen(QPen(Qt::red, 2));  
        isSelected = false;  
        flashTimer = new QTimer(this);  
        connect(flashTimer, &QTimer::timeout, this, &FlashingRectItem::toggleColor);  
    }  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        if (isSelected) {  
            setPen(QPen(Qt::red, 2));  
            flashTimer->stop();  
        } else {  
            flashTimer->start(500); // 设置闪烁频率为0.5秒  
        }  
        isSelected = !isSelected;  
        update();  
    }  
  
private:  
    void toggleColor() {  
        if (isSelected) {  
            if (pen().color() == Qt::red) {  
                setPen(QPen(Qt::blue, 2));  
            } else {  
                setPen(QPen(Qt::red, 2));  
            }  
            update();  
        }  
    }  
  
    bool isSelected;  
    QTimer *flashTimer;  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    QGraphicsScene scene;  
    FlashingRectItem *rectItem = new FlashingRectItem();  
    scene.addItem(rectItem);  
    QGraphicsView view(&scene);  
    view.show();  
    return app.exec();  
}

这段代码创建了一个自定义的QGraphicsRectItem,它会在被选中时开始闪烁,并在再次点击时停止闪烁。你可以根据需要调整闪烁的频率和颜色。

请注意,QGraphicsRectItem并未继承QObject,所以内部不能直接使用connect,请修正代码

 

确实,QGraphicsRectItem 不继承自 QObject,因此不能直接使用信号和槽机制。为了解决这个问题,我们可以将 QTimer 放置在 FlashingRectItem 的外部,并通过一个辅助的 QObject 派生类来管理定时器和信号槽连接。以下是修正后的代码示例:


#include <QApplication>  
#include <QGraphicsView>  
#include <QGraphicsScene>  
#include <QGraphicsRectItem>  
#include <QTimer>  
#include <QObject>  
  
class FlashController : public QObject {  
    Q_OBJECT  
public:  
    FlashController(QObject *parent = nullptr) : QObject(parent) {}  
  
public slots:  
    void toggleColor(QGraphicsRectItem *item) {  
        if (item->pen().color() == Qt::red) {  
            item->setPen(QPen(Qt::blue, 2));  
        } else {  
            item->setPen(QPen(Qt::red, 2));  
        }  
    }  
};  
  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem(FlashController *controller, QGraphicsItem *parent = nullptr)  
        : QGraphicsRectItem(parent), controller(controller), isSelected(false) {  
        setRect(0, 0, 100, 100);  
        setPen(QPen(Qt::red, 2));  
        flashTimer = new QTimer(this);  
        connect(flashTimer, &QTimer::timeout, this, [this]() {  
            if (isSelected) {  
                controller->toggleColor(this);  
            }  
        });  
    }  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        QGraphicsRectItem::mousePressEvent(event);  
        isSelected = !isSelected;  
        if (isSelected) {  
            flashTimer->start(500); // 设置闪烁频率为0.5秒  
        } else {  
            flashTimer->stop();  
            setPen(QPen(Qt::red, 2)); // 恢复默认颜色  
        }  
    }  
  
private:  
    FlashController *controller;  
    QTimer *flashTimer;  
    bool isSelected;  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    QGraphicsScene scene;  
    FlashController controller;  
    FlashingRectItem *rectItem = new FlashingRectItem(&controller);  
    scene.addItem(rectItem);  
    QGraphicsView view(&scene);  
    view.show();  
    return app.exec();  
}  
  
#include "main.moc"

在这个修正后的代码中,我们创建了一个名为 FlashController 的辅助类,它继承自 QObject 并提供了一个 toggleColor 槽函数,用于切换矩形的边框颜色。FlashingRectItem 类中持有一个指向 FlashController 实例的指针,并通过 lambda 表达式连接 QTimer 的 timeout 信号到 FlashController 的 toggleColor 槽。这样,当定时器超时时,如果矩形处于选中状态,就会通过 FlashController 来切换颜色。

请注意,由于我们使用了 lambda 表达式来连接信号和槽,因此需要确保 FlashingRectItem 的构造函数中 connect 调用的上下文能够捕获 this 指针。此外,在 main 函数中,我们实例化了 FlashController 并将其传递给 FlashingRectItem 的构造函数。

最后,由于我们使用了 Qt 的信号和槽机制,需要在文件末尾包含由 moc(Meta-Object Compiler)生成的 .moc 文件,以确保信号和槽的正确连接。这通常通过在项目文件(如 .pro 文件)中配置自动完成,或者通过在源代码文件末尾包含对应的 .moc 文件来手动完成。在这个例子中,我们假设你已经正确配置了项目以处理 moc 文件,并在代码末尾包含了 main.moc

请将flashTimer = new QTimer(this); 和connect迁移到FlashController中 

为了将flashTimer和相关的connect调用迁移到FlashController中,我们可以对FlashController类进行一些修改,让它负责管理定时器和连接逻辑。这样,FlashingRectItem类将不再直接处理定时器,而是通过与FlashController的交互来实现闪烁效果。

以下是修改后的代码:


#include <QApplication>  
#include <QGraphicsView>  
#include <QGraphicsScene>  
#include <QGraphicsRectItem>  
#include <QTimer>  
  
class FlashController : public QObject {  
    Q_OBJECT  
public:  
    FlashController(QObject *parent = nullptr) : QObject(parent) {  
        flashTimer = new QTimer(this);  
        connect(flashTimer, &QTimer::timeout, this, &FlashController::onTimeout);  
    }  
  
    void startFlashing(QGraphicsRectItem *item) {  
        currentItem = item;  
        flashTimer->start(500); // 设置闪烁频率为0.5秒  
    }  
  
    void stopFlashing() {  
        flashTimer->stop();  
        currentItem = nullptr;  
    }  
  
private slots:  
    void onTimeout() {  
        if (currentItem) {  
            if (currentItem->pen().color() == Qt::red) {  
                currentItem->setPen(QPen(Qt::blue, 2));  
            } else {  
                currentItem->setPen(QPen(Qt::red, 2));  
            }  
        }  
    }  
  
private:  
    QTimer *flashTimer;  
    QGraphicsRectItem *currentItem;  
};  
  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem(QGraphicsItem *parent = nullptr)  
        : QGraphicsRectItem(parent) {  
        setRect(0, 0, 100, 100);  
        setPen(QPen(Qt::red, 2));  
    }  
  
    void setFlashController(FlashController *controller) {  
        this->controller = controller;  
    }  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        QGraphicsRectItem::mousePressEvent(event);  
        if (controller) {  
            if (pen().color() == Qt::red) {  
                controller->startFlashing(this);  
            } else {  
                controller->stopFlashing();  
                setPen(QPen(Qt::red, 2)); // 恢复默认颜色  
            }  
        }  
    }  
  
private:  
    FlashController *controller = nullptr;  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    QGraphicsScene scene;  
    FlashController controller;  
    FlashingRectItem *rectItem = new FlashingRectItem();  
    rectItem->setFlashController(&controller);  
    scene.addItem(rectItem);  
    QGraphicsView view(&scene);  
    view.show();  
    return app.exec();  
}  
  
#include "main.moc"

在这个修改后的版本中,FlashController类负责管理定时器和闪烁逻辑。它提供了startFlashingstopFlashing方法来控制闪烁的开始和结束。FlashingRectItem类通过调用setFlashController方法来关联一个FlashController实例。在mousePressEvent中,FlashingRectItem会根据当前边框颜色来决定是开始闪烁还是停止闪烁并恢复默认颜色。

请注意,这个示例假设FlashControllerFlashingRectItem的实例生命周期是适当的,并且在程序运行期间保持有效。在实际应用中,您可能需要根据具体情况调整这些类的使用方式以确保正确的资源管理和对象生命周期。

请将入口函数和其他的代码分开,因为有Q_OBJECT表示的文件必须是头文件 

确实,当使用Qt的信号和槽机制时,涉及到Q_OBJECT宏的类通常需要在头文件中声明。这是因为Q_OBJECT宏添加了一些元对象代码,这些代码需要在编译时由Qt的元对象编译器(MOC)处理。为了满足这个要求,我们可以将FlashController类放在头文件中,而将main函数和其他不直接涉及元对象的代码放在源文件中。

FlashController.h


#ifndef FLASHCONTROLLER_H  
#define FLASHCONTROLLER_H  
  
#include <QObject>  
#include <QTimer>  
#include <QGraphicsRectItem>  
  
class FlashController : public QObject {  
    Q_OBJECT  
  
public:  
    explicit FlashController(QObject *parent = nullptr);  
    void startFlashing(QGraphicsRectItem *item);  
    void stopFlashing();  
  
private slots:  
    void onTimeout();  
  
private:  
    QTimer *flashTimer;  
    QGraphicsRectItem *currentItem;  
};  
  
#endif // FLASHCONTROLLER_H

FlashController.cpp


#include "FlashController.h"  
#include <QPen>  
#include <QColor>  
  
FlashController::FlashController(QObject *parent) : QObject(parent) {  
    flashTimer = new QTimer(this);  
    connect(flashTimer, &QTimer::timeout, this, &FlashController::onTimeout);  
}  
  
void FlashController::startFlashing(QGraphicsRectItem *item) {  
    currentItem = item;  
    flashTimer->start(500); // 设置闪烁频率为0.5秒  
}  
  
void FlashController::stopFlashing() {  
    flashTimer->stop();  
    currentItem = nullptr;  
}  
  
void FlashController::onTimeout() {  
    if (currentItem) {  
        QColor currentColor = currentItem->pen().color();  
        if (currentColor == Qt::red) {  
            currentItem->setPen(QPen(Qt::blue, 2));  
        } else {  
            currentItem->setPen(QPen(Qt::red, 2));  
        }  
    }  
}

main.cpp


#include <QApplication>  
#include <QGraphicsView>  
#include <QGraphicsScene>  
#include "FlashController.h"  
  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem(QGraphicsItem *parent = nullptr)  
        : QGraphicsRectItem(parent) {  
        setRect(0, 0, 100, 100);  
        setPen(QPen(Qt::red, 2));  
    }  
  
    void setFlashController(FlashController *controller) {  
        this->controller = controller;  
    }  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        QGraphicsRectItem::mousePressEvent(event);  
        if (controller) {  
            QColor currentColor = pen().color();  
            if (currentColor == Qt::red) {  
                controller->startFlashing(this);  
            } else {  
                controller->stopFlashing();  
                setPen(QPen(Qt::red, 2)); // 恢复默认颜色  
            }  
        }  
    }  
  
private:  
    FlashController *controller = nullptr;  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    QGraphicsScene scene;  
    FlashController controller;  
    FlashingRectItem *rectItem = new FlashingRectItem();  
    rectItem->setFlashController(&controller);  
    scene.addItem(rectItem);  
    QGraphicsView view(&scene);  
    view.show();  
    return app.exec();  
}

在这个例子中,FlashController类被移到了单独的头文件和源文件中,而main函数和其他与FlashingRectItem相关的代码留在了main.cpp中。这样,FlashController类就可以被MOC正确处理,同时保持了代码的清晰和模块化。

在前面的基础上,让矩形的左右边线可以拖拽,以缩放矩形 

为了实现矩形左右边线的拖拽功能以缩放矩形,我们需要对FlashingRectItem类进行一些修改,以便它可以响应鼠标事件并相应地调整其大小。以下是一个修改后的FlashingRectItem类的实现,它允许用户通过拖拽矩形的左右边线来缩放矩形。

FlashingRectItem.h


#ifndef FLASHINGRECTITEM_H  
#define FLASHINGRECTITEM_H  
  
#include <QGraphicsRectItem>  
#include <QMouseEvent>  
  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem(QGraphicsItem *parent = nullptr);  
    void setFlashController(FlashController *controller);  
  
    enum Edge { LeftEdge, RightEdge, NoEdge };  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;  
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;  
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;  
  
private:  
    Edge detectEdge(const QPointF &pos) const;  
    void resizeRect(Edge edge, const QPointF &pos);  
  
    FlashController *controller;  
    Edge currentEdge;  
    QPointF lastMousePos;  
};  
  
#endif // FLASHINGRECTITEM_H

FlashingRectItem.cpp


#include "FlashingRectItem.h"  
#include <QPen>  
#include <QCursor>  
  
FlashingRectItem::FlashingRectItem(QGraphicsItem *parent)  
    : QGraphicsRectItem(parent), controller(nullptr), currentEdge(NoEdge) {  
    setRect(0, 0, 100, 100);  
    setPen(QPen(Qt::red, 2));  
    setFlag(QGraphicsItem::ItemIsMovable, false); // Disable moving the entire item  
}  
  
void FlashingRectItem::setFlashController(FlashController *controller) {  
    this->controller = controller;  
}  
  
FlashingRectItem::Edge FlashingRectItem::detectEdge(const QPointF &pos) const {  
    QRectF rect = boundingRect();  
    if (pos.x() < rect.left() + 10) { // Left edge detected within 10 pixels tolerance  
        return LeftEdge;  
    } else if (pos.x() > rect.right() - 10) { // Right edge detected within 10 pixels tolerance  
        return RightEdge;  
    }  
    return NoEdge;  
}  
  
void FlashingRectItem::resizeRect(Edge edge, const QPointF &pos) {  
    QRectF currentRect = boundingRect();  
    switch (edge) {  
    case LeftEdge:  
        setRect(pos.x(), currentRect.y(), currentRect.width() - (pos.x() - currentRect.left()), currentRect.height());  
        break;  
    case RightEdge:  
        setRect(currentRect.left(), currentRect.y(), pos.x() - currentRect.left(), currentRect.height());  
        break;  
    default:  
        break;  
    }  
}  
  
void FlashingRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {  
    currentEdge = detectEdge(event->pos());  
    if (currentEdge != NoEdge) {  
        lastMousePos = event->pos();  
        event->accept();  
    } else {  
        QGraphicsRectItem::mousePressEvent(event); // Call base implementation for other mouse interactions  
    }  
}  
  
void FlashingRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {  
    if (currentEdge != NoEdge) {  
        resizeRect(currentEdge, event->pos());  
        lastMousePos = event->pos();  
        event->accept();  
    } else {  
        QGraphicsRectItem::mouseMoveEvent(event);  
    }  
}  
  
void FlashingRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {  
    if (currentEdge != NoEdge) {  
        resizeRect(currentEdge, event->pos());  
        currentEdge = NoEdge; // Reset the edge after releasing the mouse button  
        event->accept();  
    } else {  
        QGraphicsRectItem::mouseReleaseEvent(event);  
    }  
}

在这个实现中,我们添加了一个detectEdge函数来检测鼠标是否位于矩形的左边缘或右边缘。如果是,则记录当前边缘,并允许通过mouseMoveEvent调整矩形的大小。在mousePressEventmouseReleaseEvent中,我们处理边缘的按下和释放逻辑。

请注意,这个实现是一个简单的示例,可能需要根据您的具体需求进行调整。

将头文件和源文件合并成一个文件就行,且在主函数中直接调用 

将头文件和源文件合并成一个单独的文件,并在其中包含一个main函数来直接调用和展示FlashingRectItem的功能,可以这样做:


#include <QApplication>  
#include <QGraphicsScene>  
#include <QGraphicsView>  
  
// FlashingRectItem 类定义  
class FlashingRectItem : public QGraphicsRectItem {  
public:  
    FlashingRectItem(QGraphicsItem *parent = nullptr)  
        : QGraphicsRectItem(parent) {  
        setRect(0, 0, 100, 100);  
        setPen(QPen(Qt::red, 2));  
        setFlag(QGraphicsItem::ItemIsMovable, false); // Disable moving the entire item  
    }  
  
protected:  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override;  
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;  
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;  
  
private:  
    enum Edge { LeftEdge, RightEdge, NoEdge };  
    Edge detectEdge(const QPointF &pos) const;  
    void resizeRect(Edge edge, const QPointF &pos);  
  
    Edge currentEdge;  
    QPointF lastMousePos;  
};  
  
// FlashingRectItem 类实现  
FlashingRectItem::Edge FlashingRectItem::detectEdge(const QPointF &pos) const {  
    QRectF rect = boundingRect();  
    if (pos.x() < rect.left() + 10) return LeftEdge; // Left edge  
    if (pos.x() > rect.right() - 10) return RightEdge; // Right edge  
    return NoEdge;  
}  
  
void FlashingRectItem::resizeRect(Edge edge, const QPointF &pos) {  
    QRectF currentRect = boundingRect();  
    switch (edge) {  
    case LeftEdge:  
        setRect(pos.x(), currentRect.y(), currentRect.width() - (pos.x() - currentRect.left()), currentRect.height());  
        break;  
    case RightEdge:  
        setRect(currentRect.left(), currentRect.y(), pos.x() - currentRect.left(), currentRect.height());  
        break;  
    default:  
        break;  
    }  
}  
  
void FlashingRectItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {  
    currentEdge = detectEdge(event->pos());  
    if (currentEdge != NoEdge) {  
        lastMousePos = event->pos();  
        event->accept();  
    } else {  
        QGraphicsRectItem::mousePressEvent(event);  
    }  
}  
  
void FlashingRectItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {  
    if (currentEdge != NoEdge) {  
        resizeRect(currentEdge, event->pos());  
        lastMousePos = event->pos();  
        event->accept();  
    } else {  
        QGraphicsRectItem::mouseMoveEvent(event);  
    }  
}  
  
void FlashingRectItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {  
    if (currentEdge != NoEdge) {  
        resizeRect(currentEdge, event->pos());  
        currentEdge = NoEdge;  
        event->accept();  
    } else {  
        QGraphicsRectItem::mouseReleaseEvent(event);  
    }  
}  
  
// 主函数  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
  
    QGraphicsScene scene;  
    FlashingRectItem *rectItem = new FlashingRectItem();  
    scene.addItem(rectItem);  
  
    QGraphicsView view(&scene);  
    view.show();  
  
    return app.exec();  
}

这段代码将FlashingRectItem类的定义和实现合并到了一个文件中,并添加了一个main函数,该函数创建了一个QApplication实例、一个QGraphicsScene以及一个FlashingRectItem对象,并将其添加到场景中。最后,通过QGraphicsView来显示这个场景,并启动事件循环。现在,当你运行这个程序时,你应该能够看到一个红色的矩形,并且可以通过拖拽其左右边缘来缩放它。

qt 6.7 画一个矩形,两侧的边线粗3,上下的边线是粗1 

在 Qt 6.7 中,要绘制一个矩形,其中两侧的边线粗3,上下的边线粗1,你可以使用 QPainter 类。以下是一个简单的示例代码,展示了如何实现这一需求:


#include <QPainter>  
#include <QWidget>  
#include <QApplication>  
  
class CustomWidget : public QWidget {  
protected:  
    void paintEvent(QPaintEvent *event) override {  
        QPainter painter(this);  
        painter.setRenderHint(QPainter::Antialiasing, true);  
  
        // 设置画笔为黑色,用于绘制边框  
        QPen pen(Qt::black);  
  
        // 绘制两侧的粗边线  
        pen.setWidth(3);  
        painter.setPen(pen);  
        painter.drawLine(0, 0, 0, height()); // 左侧边线  
        painter.drawLine(width() - 3, 0, width() - 3, height()); // 右侧边线  
  
        // 绘制上下的细边线  
        pen.setWidth(1);  
        painter.setPen(pen);  
        painter.drawLine(0, 0, width(), 0); // 上边线  
        painter.drawLine(0, height() - 1, width(), height() - 1); // 下边线  
  
        // 填充矩形内部(可选)  
        painter.setBrush(Qt::white);  
        painter.drawRect(1, 1, width() - 4, height() - 2);  
    }  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    CustomWidget widget;  
    widget.resize(400, 300);  
    widget.show();  
    return app.exec();  
}

这段代码定义了一个自定义的 QWidget 类,在 paintEvent 方法中使用 QPainter 来绘制矩形。首先,它使用粗为3的画笔绘制两侧的边线,然后使用粗为1的画笔绘制上下边线。最后,它还可以选择填充矩形的内部。在 main 函数中,我们创建了这个自定义窗口的实例并显示它。

请注意,这段代码是一个简化的示例,用于演示如何在 Qt 中自定义绘图。在实际应用中,你可能需要根据具体需求进行调整。

qt 6.7 画一个矩形,两侧的边线粗3,上下的边线是粗1,用QGraphicsRectItem画 

在Qt 6.7中,使用QGraphicsRectItem来绘制一个矩形,并设置两侧边线粗为3,上下边线粗为1,可以通过自定义一个QGraphicsRectItem的子类并实现其paint()方法来完成。以下是一个简单的代码示例:


#include <QGraphicsRectItem>  
#include <QPainter>  
#include <QStyleOptionGraphicsItem>  
#include <QGraphicsScene>  
#include <QGraphicsView>  
#include <QApplication>  
  
class CustomRectItem : public QGraphicsRectItem {  
public:  
    CustomRectItem(QGraphicsItem *parent = nullptr) : QGraphicsRectItem(parent) {  
        setRect(0, 0, 100, 100); // 设置初始大小和位置  
    }  
  
protected:  
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override {  
        QPen sidePen(Qt::black, 3); // 两侧边线的画笔,线宽为3  
        QPen topBottomPen(Qt::black, 1); // 上下边线的画笔,线宽为1  
  
        painter->setPen(sidePen);  
        painter->drawLine(rect().left(), rect().top(), rect().left(), rect().bottom()); // 左侧边线  
        painter->drawLine(rect().right(), rect().top(), rect().right(), rect().bottom()); // 右侧边线  
  
        painter->setPen(topBottomPen);  
        painter->drawLine(rect().left(), rect().top(), rect().right(), rect().top()); // 上边线  
        painter->drawLine(rect().left(), rect().bottom(), rect().right(), rect().bottom()); // 下边线  
    }  
};  
  
int main(int argc, char *argv[]) {  
    QApplication app(argc, argv);  
    QGraphicsScene scene;  
    CustomRectItem *rectItem = new CustomRectItem();  
    scene.addItem(rectItem);  
    QGraphicsView view(&scene);  
    view.show();  
    return app.exec();  
}

这段代码创建了一个CustomRectItem类,它是QGraphicsRectItem的子类。在paint()方法中,我们自定义了矩形的绘制方式,使用不同线宽的画笔来分别绘制两侧和上下的边线。在main()函数中,我们创建了一个CustomRectItem实例,并将其添加到QGraphicsScene中,然后通过QGraphicsView来显示这个场景。

qt 6.7 画一个矩形,要求点击的时候边线闪烁,且两边的边线,中间有一个实心的圆形 

在 Qt 6.7 中,要实现一个矩形,在点击时边线闪烁,并且在两侧边线的中间有一个实心的圆形,你可以通过继承 QGraphicsItem 或 QGraphicsRectItem 并重写其 paint() 和 mousePressEvent() 方法来实现。以下是一个简单的示例代码:


#include <QGraphicsItem>  
#include <QPainter>  
#include <QStyleOptionGraphicsItem>  
#include <QTimer>  
#include <QGraphicsSceneMouseEvent>  
  
class FlashingRectItem : public QGraphicsItem {  
public:  
    FlashingRectItem() {  
        // 初始化闪烁状态和时间间隔  
        flashing = false;  
        flashTimer = new QTimer(this);  
        connect(flashTimer, &QTimer::timeout, this, &FlashingRectItem::update);  
    }  
  
    QRectF boundingRect() const override {  
        return QRectF(0, 0, 100, 50); // 设置矩形的尺寸  
    }  
  
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override {  
        QPen pen(Qt::black, 2);  
        if (flashing) {  
            pen.setColor(flashColor);  
        }  
  
        painter->setPen(pen);  
        painter->setBrush(Qt::NoBrush);  
        painter->drawRect(boundingRect());  
  
        // 绘制中间的实心圆形  
        painter->setBrush(Qt::black);  
        painter->drawEllipse(QPointF(50, 25), 5, 5); // 假设矩形宽100高50,圆形在中心位置  
    }  
  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        if (event->button() == Qt::LeftButton) {  
            startFlashing();  
        }  
        QGraphicsItem::mousePressEvent(event);  
    }  
  
private:  
    void startFlashing() {  
        flashing = true;  
        flashColor = Qt::red; // 设置闪烁颜色为红色  
        flashTimer->start(500); // 设置闪烁时间间隔为500毫秒  
    }  
  
    void stopFlashing() {  
        flashing = false;  
        flashTimer->stop();  
        update(); // 停止闪烁后更新一次界面  
    }  
  
protected:  
    void timerEvent(QTimerEvent *event) override {  
        if (event->timerId() == flashTimer->timerId()) {  
            flashColor = (flashColor == Qt::red) ? Qt::black : Qt::red; // 切换颜色  
            update();  
        }  
    }  
  
private:  
    QTimer *flashTimer;  
    bool flashing;  
    QColor flashColor;  
};

在这个例子中,FlashingRectItem 类继承自 QGraphicsItem。当矩形被点击时,会触发 mousePressEvent(),从而开始边线闪烁效果。闪烁效果是通过定时器 flashTimer 实现的,它每隔一段时间就会触发 timerEvent(),在这个事件处理函数中,我们切换边线的颜色并更新界面,从而实现闪烁效果。

请注意,这个示例代码是一个简化的版本,仅用于演示基本概念。在实际应用中,你可能需要根据具体需求调整矩形的尺寸、圆形的位置和大小、闪烁的颜色和频率等。

要在 Qt 应用程序中使用这个自定义图形项,你可以将其添加到 QGraphicsScene 中,并通过 QGraphicsView 显示出来。

qt 6.7 画一个矩形,要求点击的时候边线闪烁,且两边的边线的中间有一个实心的圆形 

在Qt 6.7中,要实现一个矩形,在点击时其边线闪烁,并且在两侧边线的中间位置各有一个实心的圆形,你可以通过创建一个自定义的QGraphicsItem类来完成。以下是一个简单的示例代码,展示了如何实现这个功能:


#include <QGraphicsItem>  
#include <QPainter>  
#include <QStyleOptionGraphicsItem>  
#include <QTimer>  
#include <QGraphicsSceneMouseEvent>  
  
class FlashingRectWithCirclesItem : public QGraphicsItem {  
public:  
    FlashingRectWithCirclesItem() {  
        // 初始化闪烁定时器  
        flashTimer = new QTimer(this);  
        connect(flashTimer, &QTimer::timeout, this, &FlashingRectWithCirclesItem::toggleFlashing);  
        flashing = false;  
    }  
  
    QRectF boundingRect() const override {  
        // 假设矩形的尺寸为100x50  
        return QRectF(0, 0, 100, 50);  
    }  
  
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override {  
        QPen pen(Qt::black, 2);  
        if (flashing) {  
            pen.setColor(Qt::red); // 闪烁时的颜色  
        }  
  
        painter->setPen(pen);  
        painter->setBrush(Qt::NoBrush);  
        painter->drawRect(boundingRect());  
  
        // 绘制两侧边线中间的实心圆形  
        painter->setBrush(Qt::black);  
        // 假设矩形宽100高50,在两侧边的中间位置绘制圆形  
        painter->drawEllipse(QPointF(10, 25), 5, 5); // 左侧圆形  
        painter->drawEllipse(QPointF(90, 25), 5, 5); // 右侧圆形  
    }  
  
    void mousePressEvent(QGraphicsSceneMouseEvent *event) override {  
        if (event->button() == Qt::LeftButton) {  
            if (!flashTimer->isActive()) {  
                flashing = true;  
                flashTimer->start(500); // 每500毫秒切换一次闪烁状态  
            }  
        }  
        QGraphicsItem::mousePressEvent(event);  
    }  
  
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override {  
        if (event->button() == Qt::LeftButton) {  
            flashTimer->stop();  
            flashing = false;  
            update(); // 停止闪烁后更新界面  
        }  
        QGraphicsItem::mouseReleaseEvent(event);  
    }  
  
private:  
    void toggleFlashing() {  
        flashing = !flashing;  
        update(); // 更新界面以反映闪烁状态的变化  
    }  
  
private:  
    QTimer *flashTimer;  
    bool flashing;  
};

在这个例子中,FlashingRectWithCirclesItem类继承自QGraphicsItem。在paint()方法中,我们根据flashing变量的状态来决定矩形边线的颜色,并绘制两个实心圆形在矩形的两侧。当用户点击这个图形项时,会触发mousePressEvent(),从而开始闪烁效果。当用户释放鼠标按钮时,mouseReleaseEvent()会被调用,停止闪烁效果。

要在Qt应用程序中使用这个自定义图形项,你可以像之前提到的那样将其添加到QGraphicsScene中,并通过QGraphicsView显示出来。

请注意,这个例子是为了演示目的而简化的。在实际应用中,你可能需要调整矩形的尺寸、圆形的位置和大小,以及闪烁的频率和颜色等。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值