QT开发:基于Qt实现的交通信号灯模拟器:实现一个带有倒计时功能的图形界面应用

news2024/11/19 10:22:03

介绍

        本文将介绍如何使用Qt框架实现一个简单的交通信号灯控制程序。本程序包括一个图形界面,显示红、黄、绿三色信号灯,并通过定时器控制信号灯的切换。同时,我们还将实现一个带有按钮的界面,用于展示信号灯的状态。

1. 安装Qt开发环境

        如果你还没有安装Qt开发环境,请前往Qt官网下载并安装最新的Qt版本。安装过程中请确保选择了Qt Creator和相应的Qt版本(如Qt 5或Qt 6)。本文所示例子基于Qt 5.12版本实现。

2. 创建新项目

2.1 打开Qt Creator

启动Qt Creator开发环境。

2.2 创建新项目

  1. 在Qt Creator主界面,点击File -> New File or Project
  2. 在弹出的窗口中,选择Application -> Qt Widgets Application,然后点击Choose...按钮。
  3. 输入项目名称,例如trafficlightApp,选择项目保存路径,然后点击Next
  4. 选择合适的Qt版本和编译器配置,然后点击Next
  5. 确认类名设置,默认情况下,主窗口类名为MainWindow。你可以保留默认值或者修改,点击Next
  6. 点击Finish,Qt Creator会自动生成一个新的Qt Widgets项目。

3. 设置项目结构

3.1 添加必要文件

在项目创建完成后,你可以看到Qt Creator已经为你生成了基本的项目结构。接下来,我们需要手动添加一些文件。

  1. 在项目视图中右键点击项目名称(trafficlightApp),选择Add New...
  2. 选择C++ Class,然后点击Choose...
  3. 输入类名为TrafficLightWidget,基类选择QWidget,然后点击Next,再点击Finish
  4. 使用相同的方法,再添加一个类Widget,基类选择QWidget

我们的项目结构如下:

trafficlightApp/
├── images/
│   ├── green.png
│   ├── red.png
│   └── yellow.png
├── trafficlightApp.pro
├── main.cpp
├── trafficlightwidget.cpp
├── trafficlightwidget.h
├── widget.cpp
├── widget.h
└── widget.ui

4. 编写代码

4.1 修改trafficlightApp.pro文件

        编辑项目文件trafficlightApp.pro,添加资源文件信息,若为windows系统上QT Creator创建的项目trafficlightApp.pro不要修改,会自动配置;在Ubuntu系统上需要手动在文件中添加源文件和头文件等。

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    trafficlightwidget.cpp \
    widget.cpp

HEADERS += \
    trafficlightwidget.h \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

DISTFILES += \
    images/green.png \
    images/red.png \
    images/yellow.png

4.2 编写main.cpp

#include "trafficlightwidget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    TrafficLightWidget w;
    w.show();
    return a.exec();
}

4.3 编写trafficlightwidget.h

#ifndef TRAFFICLIGHTWIDGET_H
#define TRAFFICLIGHTWIDGET_H

#include <QWidget>
#include <QTimer>

class TrafficLightWidget : public QWidget
{
    Q_OBJECT

public:
    explicit TrafficLightWidget(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;

private slots:
    void updateLight();

private:
    QTimer *timer;
    int lightIndex; // 0 for red, 1 for yellow, 2 for green
    int redDuration; // Duration for red light in ms
    int yellowDuration; // Duration for yellow light in ms
    int greenDuration; // Duration for green light in ms
    int elapsedTime; // Time elapsed since last change in ms
    int remainingTime; // Remaining time for current light in seconds

    int getLightDuration(int light) const; // Function to get the duration for the given light
};

#endif // TRAFFICLIGHTWIDGET_H

4.4 编写trafficlightwidget.cpp

#include "trafficlightwidget.h"
#include <QPainter>

TrafficLightWidget::TrafficLightWidget(QWidget *parent)
    : QWidget(parent),
      lightIndex(0), // Start with red light
      redDuration(30000), // Red duration 30 seconds
      yellowDuration(3000), // Yellow duration 3 seconds
      greenDuration(30000), // Green duration 30 seconds
      elapsedTime(0), // Reset elapsed time
      remainingTime(redDuration / 1000) // Start with red light's duration
{
    setFixedSize(200, 660); // Set the size of the traffic light widget to include countdown

    // Set up the timer to tick every second (1000 milliseconds)
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &TrafficLightWidget::updateLight);
    timer->start(1000); // Start the timer
}

void TrafficLightWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    QColor lightRed(255, 0, 0, 255);
    QColor lightYellow(255, 255, 0, 255);
    QColor lightGreen(0, 255, 0, 255);
    QColor lightOff(50, 50, 50, 255);

    // Draw the traffic light frame
    painter.setBrush(Qt::black);
    painter.drawRect(10, 10, 180, 580);

    // Draw the red light
    painter.setBrush(lightIndex == 0 ? lightRed : lightOff);
    painter.drawEllipse(40, 30, 120, 120);

    // Draw the yellow light
    painter.setBrush(lightIndex == 1 ? lightYellow : lightOff);
    painter.drawEllipse(40, 180, 120, 120);

    // Draw the green light
    painter.setBrush(lightIndex == 2 ? lightGreen : lightOff);
    painter.drawEllipse(40, 330, 120, 120);

    // Draw the countdown timer
    painter.setPen(Qt::white);
    QFont font = painter.font();
    font.setPointSize(24);
    painter.setFont(font);
    QString remainingTimeString = QString::number(remainingTime);
    painter.drawText(QRect(40, 530, 120, 50), Qt::AlignCenter, remainingTimeString);
}

void TrafficLightWidget::updateLight()
{
    // Update remaining time for the current light
    remainingTime = (getLightDuration(lightIndex) - elapsedTime) / 1000;

    elapsedTime += 1000; // Add 1 second to elapsed time

    // Check if the current light duration has passed
    if (elapsedTime >= getLightDuration(lightIndex)) {
        lightIndex = (lightIndex + 1) % 3; // Cycle through the lights
        elapsedTime = 0; // Reset elapsed time
        remainingTime = getLightDuration(lightIndex) / 1000; // Reset remaining time
    }

    update(); // Request a repaint
}

int TrafficLightWidget::getLightDuration(int light) const
{
    switch (light) {
        case 0: return redDuration; // Red light duration
        case 1: return yellowDuration; // Yellow light duration
        case 2: return greenDuration; // Green light duration
        default: return 0; // Default case (should not be reached)
    }
}

4.5 编写widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_toolButton_clicked();

    void on_pushButton_clicked();

    void on_pushButton_2_clicked();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

4.6 编写widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QGraphicsEffect>
#include<QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // Set up button styles
    ui->pushButton->setStyleSheet("border-radius: 50%; background-color: #ff0000;");
    ui->pushButton_2->setStyleSheet("border-radius: 50%; background-color: rgb(85, 255, 0);");
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_toolButton_clicked()
{
    // Placeholder for tool button click event
}

void Widget::on_pushButton_clicked()
{
    QMessageBox::information(this,"提示:","红灯,请等待!");
}

void Widget::on_pushButton_2_clicked()
{
     QMessageBox::information(this,"提示:","绿灯,请通行!");
}

4.7 编辑widget.ui

在Qt Designer中打开widget.ui文件:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>红绿灯模拟程序</string>
  </property>
  <widget class="QCheckBox" name="checkBox">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>10</y>
     <width>81</width>
     <height>31</height>
    </rect>
   </property>
   <property name="text">
    <string>CheckBox</string>
   </property>
  </widget>
  <widget class="QToolButton" name="toolButton">
   <property name="geometry">
    <rect>
     <x>710</x>
     <y>0</y>
     <width>71</width>
     <height>31</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">border-color: rgb(0, 255, 255);
border-left-color: qradialgradient(spread:pad, cx:0.5, cy:0.5, radius:0.5, fx:0.5, fy:0.5, stop:0 rgba(0, 0, 0, 0), stop:0.52 rgba(0, 0, 0, 0), stop:0.565 rgba(82, 121, 76, 33), stop:0.65 rgba(159, 235, 148, 64), stop:0.721925 rgba(255, 238, 150, 129), stop:0.77 rgba(255, 128, 128, 204), stop:0.89 rgba(191, 128, 255, 64), stop:1 rgba(0, 0, 0, 0));</string>
   </property>
   <property name="text">
    <string>Click Me</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton">
   <property name="geometry">
    <rect>
     <x>30</x>
     <y>100</y>
     <width>100</width>
     <height>100</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color:white;
border-radius:5px;
border:1px solid  black;
color:#587fba;</string>
   </property>
   <property name="text">
    <string>MyButton</string>
   </property>
   <property name="flat">
    <bool>false</bool>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_2">
   <property name="geometry">
    <rect>
     <x>330</x>
     <y>100</y>
     <width>100</width>
     <height>100</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">background-color:rgb(85, 255, 0);
border-radius:5px;
border:1px solid  black;
color:#587fba;</string>
   </property>
   <property name="text">
    <string>MyButton</string>
   </property>
   <property name="flat">
    <bool>false</bool>
   </property>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

配置这些控件的属性,如位置、文本内容和样式表等,可以参考前面提供的widget.ui文件内容。

5. 构建和运行项目

点击Qt Creator中的Build按钮来构建项目。如果项目配置正确且代码无误,构建过程应能成功完成。

        点击Run按钮,运行程序。你将看到一个包含交通信号灯和两个按钮的窗口。红色、黄色、绿色信号灯会根据设定的时长自动切换。

运行结果展示:

4ec0e1f533f94a1b8a5cd0bbae78a090.png            091ad3c21227481f9e565a357e1cc5f2.png               cce42fb233b140eda43fc7030053a743.png

通过上述详细步骤,你已经完成了一个基于Qt的简单交通信号灯控制程序的实现。希望这些说明对你有所帮助。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2177562.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux下的git开篇第一文:git的意义

目录 1.git版本控制器 2.git gitee&&github 3.Linux中gitee的使用 &#xff08; 三板斧 git add git commit -m " " git push &#xff09; 4.git log 查看之前的修改信息 &#xff08;所有提交日志&#xff09; 5.git status 查看工作目录与本地…

三防手机也能实现双卫星通信?智慧应急再添一员猛将!

随着可重复使用运载火箭技术取得显著进展&#xff0c;民营航天快速发展&#xff0c;商业卫星的发射成本不断降低&#xff0c;卫星通信全面普及的时代即将来临。遨游通讯提前布局双卫星通信技术&#xff0c;AORO M5-5G三防手机集成了天通卫星电话与北斗短报文两大国产通信技术。…

怎么将excel表格数据自动生成二维码?批量静态二维码转换的方法

在日常生活中&#xff0c;遇到需要大量二维码制作需求时&#xff0c;比如说需要给同一批产品生成不同编号的二维码时&#xff0c;有什么方法能够快速批量生成二维码呢&#xff1f;如果一个个二维码去制作不仅需要浪费大量的时间&#xff0c;而且也比较容易出错&#xff0c;那么…

MATLAB读取TIF文件,并可视化

在GIS领域&#xff0c;TIF文件则常用于存储地图、地形图等地理空间数据&#xff0c;TIF文件用于地理信息系统时&#xff0c;它通常包含地理坐标、投影信息等地理元数据&#xff0c;这些元数据使得图像能够与地理信息系统无缝集成&#xff0c;便于进行地理定位和分析。 1.读取T…

初始C++模板

1.泛型编程 1.1什么事泛型编程 在学习C语言时&#xff0c;我们时常会有这样的烦恼&#xff1a; 在针对每一种不同的类型变量进行函数传参或者是运算处理时&#xff0c;我们总是编写不同的函数或者是进行不同的处理&#xff0c;才能达到目的&#xff0c;这时&#xff0c;我们…

【JavaEE初阶】深入解析单例模式中的饿汉模式,懒汉模式的实现以及线程安全问题

前言&#xff1a; &#x1f308;上期博客&#xff1a;【JavaEE初阶】深入理解wait和notify以及线程饿死的解决-CSDN博客 &#x1f525;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 ⭐️小编会在后端开发的学习中不断更新~~~ &#x1f973;非常感谢你的…

YOLOv8改进 - 注意力篇 - 引入LSKA注意力机制

一、本文介绍 作为入门性篇章&#xff0c;这里介绍了LSKA注意力在YOLOv8中的使用。包含LSKA原理分析&#xff0c;LSKA的代码、LSKA的使用方法、以及添加以后的yaml文件及运行记录。 二、LSKA原理分析 LSKA官方论文地址&#xff1a;LSKA文章 LSKA注意力机制&#xff08;大可分…

胤娲科技:揭秘AI记忆宫殿—LLM如何用动画玩转乔丹打篮球的秘密

当AI遇上“乔丹打篮球”&#xff0c;真相竟然藏在动画里&#xff1f; 想象一下&#xff0c;你向一位AI大模型轻声询问&#xff1a;“迈克尔・乔丹从事的体育运动是……”几乎在瞬间&#xff0c;它就自信满满地回答&#xff1a;“篮球&#xff01;” 这一刻&#xff0c;你是否曾…

ROS理论与实践学习笔记——2 ROS通信机制之服务通信

服务通信也是ROS中一种极其常用的通信模式&#xff0c;服务通信是基于请求响应模式的&#xff0c;是一种应答机制。也即: 一个节点A向另一个节点B发送请求&#xff0c;B接收处理请求并产生响应结果返回给A&#xff0c;用于偶然的、对时时性有要求、有一定逻辑处理需求的数据传输…

电脑usb接口控制软件有哪些?六款软件帮你轻松管控USB端口!

小明&#xff08;疑惑地&#xff09;&#xff1a;“小李&#xff0c;我们公司最近对数据安全特别重视&#xff0c;我听说可以通过软件来控制电脑的USB接口&#xff0c;防止数据泄露。你知道有哪些好用的USB接口控制软件吗&#xff1f;” 小李&#xff08;自信地&#xff09;&a…

双十一买什么好?五大双十一好物推荐!

每年的双十一购物节都是消费者期待已久的盛事&#xff0c;届时各大电商平台纷纷推出优惠活动&#xff0c;吸引了无数购物爱好者的目光。双十一买什么好&#xff1f;为了帮助大家在双十一期间高效购物&#xff0c;我们精心挑选了五大双十一好物推荐&#xff01;这些产品不仅在品…

C++之STL—函数对象谓词

函数对象&#xff08;仿函数&#xff09; 函数对象(仿函数)是一个**类**&#xff0c;不是一个函数 类名&#xff08;&#xff09; 仿函数 直接调用&#xff1a; 、 谓词 定义&#xff1a;返回类型为bool 类型的仿函数 一元谓词&#xff1a;operator()接受一个参数 二元谓词&a…

智能家居新体验:Zigbee2MQTT与Tuya生态的完美结合

01 前言 本文章原文发表于我的微信公众号&#xff0c;请大家关注阅读&#xff0c;涉及的源代码等都在公众号&#xff0c;请搜索公众号&#xff1a; 智能家居NodeRed和HomeAssistant 即可关注。 02 概述 在智能家居领域&#xff0c;Zigbee2MQTT已经成为了许多爱好者和开发者的…

常见字符函数和字符串函数(下)

1. strncpy 函数的使用 将源的前 number 个字符复制到目标。如果在复制 num 个字符之前找到源 C 字符串的末尾&#xff08;由 null 字符表示&#xff09;&#xff0c;则目标将填充零&#xff0c;直到写入总数 num 个字符为止。如果 source 长于 num&#xff0c;则不会在 destin…

目标检测 DETR(2020)

文章目录 前言backbone位置编码&#xff08;二维&#xff09;encoder、decoderprediction heads损失函数计算 前言 DETR全称是Detection Transformer&#xff0c;是首个基于Transformer的端到端目标检测网络&#xff0c;最大的特点就是不需要预定义的先验anchor&#xff0c;也…

项目没亮点?那就来学下pk功能设计吧

先赞后看&#xff0c;南哥助你Java进阶一大半 麻省理工学院开源的Redis adapter适配器&#xff0c;可以将事件广播到多个单独的 socket.io 服务器节点。这一点和下文精彩的内容相关。 我是南哥&#xff0c;一个Java学习与进阶的领路人。 相信对你通关面试、拿下Offer进入心心念…

湖州市自闭症寄宿学校:个性化教育培养孩子潜能

在湖州市&#xff0c;自闭症寄宿学校正积极探索个性化教育的道路&#xff0c;致力于为自闭症儿童提供最适合他们成长与发展的教育环境。这一理念不仅在当地得到了实践&#xff0c;更在全国范围内产生了深远的影响。今天&#xff0c;我们将目光投向广州&#xff0c;深入了解星贝…

头戴式蓝牙耳机哪个品牌比较好?西圣、声阔、QCY热款实测性能PK

头戴式蓝牙耳机凭借其卓越的音质表现、沉浸式的听音体验以及出色的降噪功能&#xff0c;成为了众多音乐爱好者和通勤人士的首选&#xff0c;随着技术的不断进步&#xff0c;西圣、声阔、QCY等知名品牌纷纷推出了各具魅力的头戴式蓝牙耳机产品&#xff0c;面对它们家的耳机&…

十进制与ip地址转换公式(EXCEL公式)

1、十进制转为ip地址公式 TEXT(INT(C2/16777216),“0”)&“.”&TEXT(INT((C2-INT(C2/16777216)*16777216)/65536),“0”)&“.”&TEXT(INT((C2-INT(C2/16777216)*16777216-INT((C2-INT(C2/16777216)*16777216)/65536)*65536)/256),“0”)&“.”&TEXT(MO…

城市空间设计对居民生活质量的影响:构建宜居城市的蓝图

在快节奏的现代生活中&#xff0c;城市不仅是经济活动的中心&#xff0c;更是人们生活、工作、休闲的综合载体。本文旨在深入探讨城市空间设计如何通过科学规划、人性化考量以及生态融合&#xff0c;为居民打造更加宜居、和谐的生活环境。 1. 促进社区互动与归属感 城市空间设…