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

介绍

本文将介绍如何使用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

我们的项目结构如下:

cpp 复制代码
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系统上需要手动在文件中添加源文件和头文件等。

cpp 复制代码
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

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

cpp 复制代码
#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

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

cpp 复制代码
#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

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文件:

cpp 复制代码
<?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按钮,运行程序。你将看到一个包含交通信号灯和两个按钮的窗口。红色、黄色、绿色信号灯会根据设定的时长自动切换。

运行结果展示:

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

相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner13 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner14 天前
DicomViewer (目录调整) 2
qt
xcyxiner14 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00616 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术16 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript