3456 views|10 replies

291

Posts

5

Resources
The OP
 

Embedded Qt-Make a stopwatch [Copy link]

This post was last edited by DDZZ669 on 2022-8-7 15:55

Previous article: Embedded Qt - Write and run your first ARM-Qt program

This paper introduces how to write the first embedded Qt program and implements a demonstration of an electronic clock.

In this article, we continue to practice Qt and implement a stopwatch with the same function as the stopwatch in the mobile phone:

Looking back at the last Qt development process, the entire Qt development is achieved by typing code. In fact, you can also use the UI interface function of Qt Creater to develop a graphical interface through graphical configuration. This article will use this method for development.

1 Create a new Qt project

For the specific steps of creating a Qt project, please refer to the previous article: Embedded Qt - Write and run your first ARM-Qt program . Only the differences are explained here.

The previous article implemented page design through code. This article will use the UI interface design function of Qt Creater, so you need to check the following creation page :

After creation, the Qt default project structure is as follows:

Double-click widget.ui to open the UI settings page, as shown below:

Here is a brief introduction to each functional area:

2. Code Writing

2.1 UI interface design

Change the size of the interface. The resolution of my Linux board screen is 800x480, so adjust it to the corresponding size:

Drag a Label from the left , and then you can modify the font size:

Then drag in other components you need from the left ( PushButton , TextBrower ) and position adjustment components (spring-shaped HorizontalSpacer , VericalSpacer )

To perform horizontal and vertical layout, select the corresponding components, such as the three buttons and the two springs in the middle, and click the horizontal layout button in the upper toolbar:

The horizontal layout of the three buttons is as follows:

Then lay out the other components in turn:

The font can be adjusted to be displayed in the center:

Select the largest component with the mouse, drag the edge to adjust it to the appropriate outer size. Then select components of different levels, adjust the parameters of layoutStretch, and display each component in proportion (equivalent to adjusting the elasticity of each spring component).

Click the triangle icon on the lower left corner, run, and see the effect:

Note that the blank space on the left is for the stopwatch dial.

2.2 Introduction to QTimer and QTime

The QTimer class provides a high-level programming interface for timers, providing both repeating and one-shot timing.

The QTime class provides clock time functionality. A QTime object contains a clock time, which can be expressed as the number of hours, minutes, seconds, and milliseconds since midnight.

Qt Creater provides convenient help documentation. You can directly view the usage of corresponding functions in Qt Creater. For example, search for QTimer to see the corresponding introduction and available API functions:

The functions of QTimer needed in this article are:

  • start: Start the timer

  • stop: Stop the timer

Let's take a look at the introduction of QTime:

The functions of QTime needed in this article are:

  • setHMS: Set the initial time

  • addMSecs: add a time (in milliseconds)

  • toString: Convert time to string format

  • minute: Get the minute

  • second: Get seconds

  • msec: Get milliseconds

2.3 Functions corresponding to buttons

In order to write more understandable code, before writing the code, you need to modify the default name of the corresponding component to a name that is easy to understand. For example, I changed the names of the three buttons to:

  • Btn_Start: Start button with pause/continue function

  • Btn_Reset: Reset button

  • Btn_Hit: Hit button, used to record the time of different rankings

Then you need to manually add QTimer and QTime objects to implement the stopwatch timing function:

2.3.1 Start button processing

The important process in Qt programming is the signal and slot mechanism, which can be implemented manually through the connet function. For the graphical interface design method using Qt Creater, it is usually necessary to continue to connect signals and slots through the interface: right click on the start button and select " Go to slot... ":

Then there are a variety of button signals to choose from. Since the start button also has the function of pause/resume, the toggled function is used here to implement the pause/resume function by using the pressed and released states of the button:

After clicking OK, it will automatically jump to the code page and automatically generate the corresponding slot function framework, and then you can compile the corresponding business logic code in it:

The specific business logic code of the start button is as follows. When it is pressed for the first time, checked is true, and the timer is started to record the timestamp at this time. Then the text of the button is displayed as "Pause", and the reset and dot buttons are grayed out so that these two buttons can no longer be pressed, because it is meaningless to execute reset and dot during pause.

The timer triggers a timeout at regular intervals. Here, ADD_TIME_MSEC is set to 30ms. After the timeout expires, write the corresponding timeout processing function timeout_slot and declare the corresponding signal and slot processing.

void Widget::on_Btn_Start_toggled(bool checked)
{
  if (checked)
   {
    timer.start(ADD_TIME_MSEC);
    lastTime = QTime::currentTime(); //Record timestamp
    ui->Btn_Start->setText("Pause");
    ui->Btn_Reset->setEnabled(false);
    ui->Btn_Hit->setEnabled(true);
   }
  else
   {
    timer.stop();
    ui->Btn_Start->setText("Continue");
    ui->Btn_Reset->setEnabled(true);
    ui->Btn_Hit->setEnabled(false);
   }
}

connect(&timer, SIGNAL(timeout()), this, SLOT(timeout_slot()));
void Widget::timeout_slot()
{
  //qDebug("hello");
  QTime nowTime = QTime::currentTime();
  time = time.addMSecs(lastTime.msecsTo(nowTime));
  lastTime = nowTime;
  ui->Txt_ShowTime->setText(time.toString("mm:ss.zzz"));
}

After the timeout is reached, the time difference between two times is calculated, and then the time is accumulated through the addMSecs function.

2.3.2 Reset button processing

The reset button is also adjusted to the slot by right clicking. Note that the clicked function can be used here, because the reset button only needs to use its click and press function:

The specific implementation of the corresponding slot function is as follows:

void Widget::on_Btn_Reset_clicked()
{
  m_iHitCnt = 0;
  timer.stop();
  time.setHMS(0,0,0,0);
  ui->Txt_ShowTime->setText("00:00:00");
  ui->Txt_ShowItem->clear();

  ui->Btn_Start->setText("Start");
  ui->Btn_Start->setChecked(false);
  ui->Btn_Reset->setEnabled(false);
  ui->Btn_Hit->setEnabled(false);
}

The main function is to reset the time to zero, display the status, and display status of each button to the default display status.

2.3.3 Processing of the click button

The click button is the same as the reset button, and only the clicked function is used. The specific implementation of the corresponding slot function is as follows:

void Widget::on_Btn_Hit_clicked()
{
  QString temp;
  m_iHitCnt++;
  temp.sprintf("--Count times%d--", m_iHitCnt);
  ui->Txt_ShowItem->setFontPointSize(9);
  ui->Txt_ShowItem->append(temp);
  ui->Txt_ShowItem->setFontPointSize(12);
  ui->Txt_ShowItem->append(time.toString("[mm:ss.zzz]"));
}

The dot function is used to record the time of different positions during the operation of the stopwatch and display it in the text display box on the right.

Here, the setFontPointSize function is used to set the font display of different sizes.

2.4 Implementation of the stopwatch dial

In the previous article: Embedded Qt - Write and run your first ARM-Qt program , a clock dial was displayed through code. Based on this article, this article modifies the code to realize a stopwatch dial that displays seconds and minutes. The specific modified code is as follows:

connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
connect(ui->Btn_Reset, SIGNAL(clicked()), this, SLOT(update()));

void Widget::paintEvent(QPaintEvent *event)
{
  int side = qMin(width(), height());
  //QTime time = QTime::currentTime();

  QPainter painter(this);
  painter.setRenderHint(QPainter::Antialiasing);
  painter.translate(width()/3, height()*2/5); //Base position of drawing
  painter.scale(side/300.0, side/300.0); //Automatically scale with window size

  //Dial (3 concentric circles)
  for (int i=0; i<PANEL_RADIUS_NUM; i++)
   {
    QBrush brush(stPanelParaArr .color);
    QPen pen(stPanelParaArr .color);
    painter.setBrush(brush);
    painter.setPen(pen);
    painter.drawEllipse(-stPanelParaArr .radius, -stPanelParaArr .radius, 2*stPanelParaArr .radius, 2*stPanelParaArr .radius);
   }

  // Seconds scale
  painter.setPen(secondColor);
  for (int i = 0; i < 60; i++)
   {
    if ((i % 5) == 0)
     {
      painter.drawLine(PANEL_RADIUS3-8, 0, PANEL_RADIUS3, 0);
      QFont font("TimesNewRoman", SEC_NUM_SIZE);
      painter.setFont(font);
      painter.drawText(-SEC_NUM_SIZE, -(CLOCK_RADIUS-15), 2*SEC_NUM_SIZE, 2*SEC_NUM_SIZE, Qt::AlignHCenter, QString::number(i==0? 60 : i));
     }
    else
     {
      painter.drawLine(PANEL_RADIUS3-5, 0, PANEL_RADIUS3, 0);
     }
    //Seconds are further divided into 5 grids
    for (int j = 0; j < 5; j++)
     {
      painter.rotate(6.0/5);
      if (j != 4)
       {
        painter.drawLine(PANEL_RADIUS3-2, 0, PANEL_RADIUS3, 0);
       }
     }
   }

  //Minute scale
  painter.setPen(minuteColor);
  for (int k = 0; k < 30; k++)
   {
    if ((k % 5) == 0)
     {
      painter.rotate(-90.0);
      painter.drawLine(PANEL_RADIUS4-8, 0, PANEL_RADIUS4, 0);
      painter.rotate(90.0);

      QFont font("TimesNewRoman", MIN_NUM_SIZE);
      painter.setFont(font);
      painter.drawText(-MIN_NUM_SIZE, -(PANEL_RADIUS4-10), 2*MIN_NUM_SIZE, 2*MIN_NUM_SIZE, Qt::AlignHCenter, QString::number(k==0? 30 : k));
     }
    else
     {
      painter.rotate(-90.0);
      painter.drawLine(PANEL_RADIUS4-4, 0, PANEL_RADIUS4, 0);
      painter.rotate(90.0);
     }
    painter.rotate(12.0);
   }

  //Minute hand
  painter.setPen(Qt::NoPen);
  painter.setBrush(minuteColor);
  painter.save();
  painter.rotate(12.0 * (time.minute() + time.second() / 60.0));
  painter.drawConvexPolygon(minuteHand, 3);
  painter.restore();

  //The second hand
  painter.setPen(Qt::NoPen);
  painter.setBrush(secondColor);
  painter.save();
  //painter.rotate(6.0 * time.second());
  painter.rotate(6.0 * (time.second()+time.msec()/1000.0));
  painter.drawConvexPolygon(secondHand, 3);
  painter.restore();

  painter.end();
}

The main modification is to remove the previous hour display and replace it with two time rings: an outer second ring and an inner minute ring . The range of the second ring is 0~60 seconds, and the range of the minute ring is 0~30 minutes.

The display effect of the stopwatch dial is as follows:

3 Compile and run

The code is written in Qt Creater in the Window environment, and is first compiled in Windows to view the effect.

3.1 Compiling in Windows

The running effect in Windows is as shown in the right picture below, which can achieve a timing effect similar to the stopwatch in the mobile phone:

3.2 Compiling in Ubuntu

The QT project source code in Windows:

  • .cpp files

  • .h files

  • .pro file

  • .ui File

Copy it to Ubuntu. Note that the .user file is not needed (it is the compilation configuration for the Windows platform).

Then use the compilation tool chain of the ARM platform. Mine is in "/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/". Here you need to use its qmake tool to automatically generate the Makefile file, and then compile it through the make command .

Use qmake to generate Makefile, enter the program source directory, and execute the qmake command:


/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake

After successful execution, you can see the automatically generated Makefile file, and then execute the make command to compile and obtain the executable file.

3.3 Running on Linux board

Put the executable file into the Linux board that has been configured with the Qt runtime environment, run it and view the effect:

Note:

For the specific compilation process in Ubuntu, please refer to the previous article: Embedded Qt - Write and run your first ARM-Qt program

For the configuration of Qt's cross-compilation environment in Ubuntu, please refer to this previous article: Embedded Linux-Qt Environment Construction

4 Conclusion

This article uses a stopwatch example to introduce how to use the UI interface design function of Qt Creator to develop Qt, cross-compile the code, and test the operation in the Linux environment of i.MX6ULL.

This post is from ARM Technology

Latest reply

I still don't understand embedded LINUX very well. I'm too new to it. I still don't understand embedded LINUX very well. I'm too new to it.   Details Published on 2022-10-11 13:12
 

6593

Posts

0

Resources
2
 

By using Qt Creator's UI interface design function, the stopwatch example is very detailed and wonderful.

This post is from ARM Technology
 
 
 

35

Posts

2

Resources
3
 

Qt [1] is a cross-platform C++ graphical user interface application development framework developed by the Qt Company in 1991. It can be used to develop both GUI programs and non-GUI programs, such as console tools and servers . Qt is an object-oriented framework that uses a special code generation extension (called the Meta Object Compiler (moc)) and some macros to make it easy to extend and allow true component programming.

In 2008, Qt Company was acquired by Nokia , and Qt became a programming language tool under Nokia. In 2012, Qt was acquired by Digia.

In April 2014, the cross-platform integrated development environment Qt Creator 3.1.0 was officially released, which fully supports iOS , adds WinRT , Beautifier and other plug-ins, abandons GDB debugging support without Python interface , integrates Clang- based C/C++ code modules, and makes adjustments to Android support, thus fully supporting iOS, Android, and WP . It provides application developers with all the functions they need to build state-of-the-art graphical user interfaces. Basically, Qt is the same type of graphical interface libraries such as Motif , Openwin, GTK on the X Window and MFC, OWL, VCL, and ATL on the Windows platform.

This post is from ARM Technology
 
 
 

1w

Posts

204

Resources
4
 

This is good! Like (≧▽≦)

This post is from ARM Technology
Add and join groups EEWorld service account EEWorld subscription account Automotive development circle
 
 
 

4771

Posts

12

Resources
5
 

It's awesome! I learned a lot. It is said that the most difficult part of clocks is the perpetual calendar, especially the handling of leap years and leap seconds.

This post is from ARM Technology
 
 
 

7462

Posts

2

Resources
6
 

The qt library is indeed very convenient to use. I am now using qtcore to do things under Linux.

This post is from ARM Technology
 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

1

Posts

0

Resources
7
 

Thanks for sharing and give it a thumbs up

This post is from ARM Technology
 
 
 

1

Posts

0

Resources
8
 

Considering everything, Qt functions are relatively simple to implement

This post is from ARM Technology
 
 
 

9

Posts

0

Resources
9
 

Really detailed, thanks for sharing

This post is from ARM Technology
 
 
 

87

Posts

0

Resources
10
 

I still don't understand embedded LINUX. I'm too new to it.

This post is from ARM Technology
 
 
 

87

Posts

0

Resources
11
 

I still don't understand embedded LINUX very well. I'm too new to it. I still don't understand embedded LINUX very well. I'm too new to it.

This post is from ARM Technology
 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list