Results 1 to 5 of 5

Thread: Main Window Title Bar with Date / Clock

  1. #1
    Join Date
    Sep 2020
    Posts
    3
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Main Window Title Bar with Date / Clock

    I am trying to learn Qt on an uBuntu 20.04 Linux Desktop Computer by means of writing a simple program to add a date/clock on its main window title bar. So, I did a google search and found only this https://www.qtcentre.org/threads/56410-Placing-Clock-on-Title-Bar?highlight=Clock+in+Window+Title (which drove me to this very forum) article. Unfortunately, the article didn't help at all. So, I decided to write my own as shown below. The program works just fine (no blinking on the separated "". However, the date/clock seems to have replaced the original Window Title. The question is how to I add the date/clock sans losing the original title? While at it, I sure would like to make the separated ":" to blink every second if possible. Anyone?

    windowtitleclock.h
    Qt Code:
    1. #ifndef WINDOWTITLECLOCK_H
    2. #define WINDOWTITLECLOCK_H
    3.  
    4. #include <QMainWindow>
    5. #include <QTimer>
    6. #include <QDateTime>
    7.  
    8. QT_BEGIN_NAMESPACE
    9. namespace Ui { class WindowTitleClock; }
    10. QT_END_NAMESPACE
    11.  
    12. class WindowTitleClock : public QMainWindow
    13. {
    14. Q_OBJECT
    15.  
    16. public:
    17. WindowTitleClock(QWidget *parent = nullptr);
    18. ~WindowTitleClock();
    19.  
    20. public slots:
    21. void windowTitleClock ();
    22.  
    23. private:
    24. Ui::WindowTitleClock *ui;
    25. QTimer *timer;
    26. };
    27. #endif // WINDOWTITLECLOCK_H
    To copy to clipboard, switch view to plain text mode 

    windowtitleclock.cpp
    Qt Code:
    1. #include "windowtitleclock.h"
    2. #include "ui_windowtitleclock.h"
    3.  
    4. WindowTitleClock::WindowTitleClock(QWidget *parent)
    5. : QMainWindow(parent)
    6. , ui(new Ui::WindowTitleClock)
    7. {
    8. ui->setupUi(this);
    9. timer = new QTimer (this);
    10. connect (timer, SIGNAL (timeout ()), this, SLOT (windowTitleClock ()));
    11. timer->start (1000);
    12. }
    13.  
    14. WindowTitleClock::~WindowTitleClock()
    15. {
    16. delete ui;
    17. }
    18.  
    19. void WindowTitleClock::windowTitleClock()
    20. {
    21. this->setWindowTitle (QDate::currentDate().toString() + " " + QTime::currentTime().toString("[hh:mm:ss]"));
    22. }
    To copy to clipboard, switch view to plain text mode 


    main.cpp
    Qt Code:
    1. #include "windowtitleclock.h"
    2.  
    3. #include <QApplication>
    4.  
    5. int main(int argc, char *argv[])
    6. {
    7. QApplication a(argc, argv);
    8. WindowTitleClock w;
    9. w.show();
    10. return a.exec();
    11. }
    To copy to clipboard, switch view to plain text mode 

    WindowTitleClock.pro
    Qt Code:
    1. QT += core gui
    2.  
    3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    4.  
    5. CONFIG += c++11
    6.  
    7. # The following define makes your compiler emit warnings if you use
    8. # any Qt feature that has been marked deprecated (the exact warnings
    9. # depend on your compiler). Please consult the documentation of the
    10. # deprecated API in order to know how to port your code away from it.
    11. DEFINES += QT_DEPRECATED_WARNINGS
    12.  
    13. # You can also make your code fail to compile if it uses deprecated APIs.
    14. # In order to do so, uncomment the following line.
    15. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    16. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
    17.  
    18. INCLUDEPATH += include
    19. SOURCES += \
    20. src/main.cpp \
    21. src/windowtitleclock.cpp
    22.  
    23. HEADERS += \
    24. include/windowtitleclock.h
    25.  
    26. FORMS += \
    27. resources/windowtitleclock.ui
    28.  
    29. TRANSLATIONS += \
    30. resources/WindowTitleClock_en_US.ts
    31.  
    32. # Default rules for deployment.
    33. qnx: target.path = /tmp/$${TARGET}/bin
    34. else: unix:!android: target.path = /opt/$${TARGET}/bin
    35. !isEmpty(target.path): INSTALLS += target
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,688
    Thanks
    257
    Thanked 748 Times in 738 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Main Window Title Bar with Date / Clock

    However, the date/clock seems to have replaced the original Window Title.
    When you call QWidget::setWindowTitle() it is doing exactly what you are telling it to do: set the title to be the string you are passing in.

    If you want the window title to contain something else in addition to your clock, then before you set the new window title for the first time, you need to retrieve the current one (QWidget::windowTitle()) and save it in a QString member variable of your QWindow-based class. When you want to update the clock, you need to take this string, add your clock string on the end, and set that as the new title. You have to use a member variable - you can't simply retrieve the title each time and add the clock. (Try it, you'll see).

    As an alternative, you might think about creating a clock widget and adding it to the status bar. QMainWindow::statusBar(), QStatusBar::addWidget()
    Last edited by d_stranz; 24th September 2020 at 18:50.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Sep 2020
    Posts
    3
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Main Window Title Bar with Date / Clock

    Quote Originally Posted by d_stranz View Post
    When you call QWidget::setWindowTitle() it is doing exactly what you are telling it to do: set the title to be the string you are passing in.

    If you want the window title to contain something else in addition to your clock, then before you set the new window title for the first time, you need to retrieve the current one (QWidget::windowTitle()) and save it in a QString member variable of your QWindow-based class. When you want to update the clock, you need to take this string, add your clock string on the end, and set that as the new title. You have to use a member variable - you can't simply retrieve the title each time and add the clock. (Try it, you'll see).
    Thank you for your quick response. I tried your suggestion and it partially works in the sense it repeatedly shows the original title + date / clock @every second to completely fill the title.

    As an alternative, you might think about creating a clock widget and adding it to the status bar. QMainWindow::statusBar(), QStatusBar::addWidget()
    As a newbie, this ain't gonna be easy for me. However, this sounds better to me and I sure will look into this approach.

    If anyone here has a better approach, I sure will welcome some feedback. Thank you all.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,688
    Thanks
    257
    Thanked 748 Times in 738 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Main Window Title Bar with Date / Clock

    and it partially works
    Well, what else do you want it to do? The title is simply a string. If you want it to do something different, then write code to change the string you have stored and let it update the title the next time the timer fires.

    If other parts of your app are also calling setWindowTitle for the main window, then that is no good because whatever they set the title to will change the next clock tick. This is why a clock in the status bar makes more sense - it is a standalone widget that doesn't change the behavior of anything else.

    Here is some code I wrote to make a digital clock with a transparent background that I can stick in a corner of my Desktop. All of the QSettings and mouse event stuff is just so I can have the clock appear in the same place on the screen after I move it, every time it starts up.

    You can easily modify the DigitalClock class to make it work as a status bar widget. See below.

    Qt Code:
    1. // main.cpp
    2.  
    3. #include "DigitalClock.h"
    4. #include <QApplication>
    5. #include <QSettings>
    6.  
    7. int main(int argc, char *argv[])
    8. {
    9. QApplication a(argc, argv);
    10.  
    11. QCoreApplication::setApplicationName( "Digital Clock" );
    12. QCoreApplication::setOrganizationName( "D_Stranz" );
    13. QCoreApplication::setOrganizationDomain( "Domains R Us" );
    14. QSettings::setDefaultFormat( QSettings::IniFormat );
    15.  
    16. DigitalClock w;
    17. w.show();
    18. return a.exec();
    19. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // DigitalClock.h
    2.  
    3. #ifndef DIGITALCLOCK_H
    4. #define DIGITALCLOCK_H
    5.  
    6. #include <QtWidgets/QWidget>
    7.  
    8. class QLabel;
    9. class QTimer;
    10.  
    11. class DigitalClock : public QWidget
    12. {
    13. Q_OBJECT
    14.  
    15. public:
    16. DigitalClock(QWidget *parent = 0);
    17. ~DigitalClock();
    18.  
    19. protected slots:
    20. void onUpdateDateTime();
    21.  
    22. protected:
    23. void mousePressEvent( QMouseEvent * pEvent ) override;
    24. void mouseMoveEvent( QMouseEvent * pEvent ) override;
    25. void mouseReleaseEvent( QMouseEvent * pEvent ) override;
    26. void showEvent( QShowEvent * pEvent ) override;
    27.  
    28. private:
    29. QLabel * mpTimeLabel;
    30. QLabel * mpDateLabel;
    31. QTimer * mpTimer;
    32.  
    33. QPoint mPos;
    34. bool mbMoving = false;
    35. };
    36.  
    37. #endif // DIGITALCLOCK_H
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. // DigitalClock.cpp
    2.  
    3. #include "DigitalClock.h"
    4.  
    5. #include <QVBoxLayout>
    6. #include <QLabel>
    7. #include <QTimer>
    8. #include <QDateTime>
    9. #include <QTime>
    10. #include <QDate>
    11. #include <QFont>
    12. #include <QMouseEvent>
    13. #include <QAction>
    14. #include <QSettings>
    15.  
    16. DigitalClock::DigitalClock(QWidget *parent)
    17. : QWidget( parent , Qt::FramelessWindowHint )
    18. {
    19. setAttribute( Qt::WA_TranslucentBackground, true );
    20. setAttribute( Qt::WA_TransparentForMouseEvents, false );
    21.  
    22. QVBoxLayout * pLayout = new QVBoxLayout( this );
    23.  
    24. QFont curFont = font();
    25. curFont.setPointSize( 52 );
    26.  
    27. mpTimeLabel = new QLabel( "" );
    28. mpTimeLabel->setFont( curFont );
    29. mpTimeLabel->setAlignment( Qt::AlignCenter );
    30.  
    31. curFont.setPointSize( 32 );
    32. mpDateLabel = new QLabel( "" );
    33. mpDateLabel->setAlignment( Qt::AlignCenter );
    34. mpDateLabel->setFont( curFont );
    35.  
    36. pLayout->addWidget( mpTimeLabel );
    37. pLayout->addWidget( mpDateLabel );
    38. setLayout( pLayout );
    39.  
    40. QAction * pExitAction = new QAction( "Exit", this );
    41. connect( pExitAction, &QAction::triggered, this, &QWidget::close );
    42.  
    43. curFont.setPointSize( 12 );
    44. setFont( curFont );
    45. setContextMenuPolicy( Qt::ActionsContextMenu );
    46. addAction( pExitAction );
    47.  
    48. mpTimer = new QTimer( this );
    49. mpTimer->setInterval( 1000 );
    50. connect( mpTimer, &QTimer::timeout, this, &DigitalClock::onUpdateDateTime );
    51. mpTimer->start();
    52.  
    53. mPos = mapToGlobal( pos() );
    54. }
    55.  
    56. DigitalClock::~DigitalClock()
    57. {
    58.  
    59. }
    60.  
    61. void DigitalClock::onUpdateDateTime()
    62. {
    63. QDateTime now = QDateTime::currentDateTime();
    64. QTime nowTime = now.time();
    65.  
    66. int hour = nowTime.hour();
    67. hour = ( hour <= 12 ? hour : hour - 12 );
    68. QString timeStr = QString( "%1:%2:%3" ).arg( hour, 2, 10, QChar(' ') ).arg( nowTime.minute(), 2, 10, QChar( '0' ) ).arg( nowTime.second(), 2, 10, QChar( '0' ) );
    69. mpTimeLabel->setText( timeStr );
    70.  
    71. QDate nowDate = now.date();
    72. QString dateStr = QString( "%1/%2/%3" ).arg( nowDate.day(), 2, 10, QChar( ' ' ) ).arg( nowDate.month(), 2, 10, QChar( '0' ) ).arg( nowDate.year(), 4 );
    73. mpDateLabel->setText( dateStr );
    74. }
    75.  
    76. void DigitalClock::mousePressEvent( QMouseEvent * pEvent )
    77. {
    78. if ( pEvent->button() == Qt::LeftButton )
    79. {
    80. mPos = mapToGlobal( pEvent->pos() );
    81. mbMoving = true;
    82. }
    83. }
    84.  
    85. void DigitalClock::mouseMoveEvent( QMouseEvent * pEvent )
    86. {
    87. if ( mbMoving )
    88. {
    89. mPos = mapToGlobal( pEvent->pos() );
    90. move( mPos );
    91. }
    92. }
    93.  
    94. void DigitalClock::mouseReleaseEvent( QMouseEvent * pEvent )
    95. {
    96. mbMoving = false;
    97.  
    98. QSettings settings;
    99. settings.beginGroup( "Global" );
    100. settings.setValue( "Position", QVariant( mPos ) );
    101. settings.endGroup();
    102. }
    103.  
    104. void DigitalClock::showEvent( QShowEvent * pEvent )
    105. {
    106. QSettings settings;
    107. settings.beginGroup( "Global" );
    108. QVariant var = settings.value( "Position" );
    109. settings.endGroup();
    110.  
    111. if ( !var.isNull() )
    112. {
    113. mPos = var.toPoint();
    114. move( mPos );
    115. }
    116.  
    117. }
    To copy to clipboard, switch view to plain text mode 

    You can try that code, and then modify it to work as a statusbar widget. This code makes an ordinary widget, changes the layout to horizontal rather than vertical (so the date and time are side-by-side). If you don't want the date, then simply delete that QLabel and change the update slot to remove the formatting for the date label. Adding the widget as a permanent widget in the status bar means that it will always be visible and never be overwritten with a status bar message.

    Qt Code:
    1. #ifndef DIGITALCLOCK_H
    2. #define DIGITALCLOCK_H
    3.  
    4. #include <QtWidgets/QWidget>
    5.  
    6. class QLabel;
    7. class QTimer;
    8.  
    9. class DigitalClock : public QWidget
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. DigitalClock(QWidget *parent = 0);
    15. ~DigitalClock();
    16.  
    17. protected slots:
    18. void onUpdateDateTime();
    19.  
    20. private:
    21. QLabel * mpTimeLabel;
    22. QLabel * mpDateLabel;
    23. QTimer * mpTimer;
    24.  
    25. };
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "DigitalClock.h"
    2.  
    3. #include <QHBoxLayout>
    4. #include <QLabel>
    5. #include <QTimer>
    6. #include <QDateTime>
    7. #include <QTime>
    8. #include <QDate>
    9.  
    10. DigitalClock::DigitalClock(QWidget *parent)
    11. : QWidget( parent )
    12. {
    13. QHBoxLayout * pLayout = new QHBoxLayout( this );
    14.  
    15. mpTimeLabel = new QLabel( "" );
    16. mpTimeLabel->setAlignment( Qt::AlignLeft );
    17.  
    18. mpDateLabel = new QLabel( "" );
    19. mpDateLabel->setAlignment( Qt::AlignRight );
    20.  
    21. pLayout->addWidget( mpTimeLabel );
    22. pLayout->addWidget( mpDateLabel );
    23. setLayout( pLayout );
    24.  
    25. mpTimer = new QTimer( this );
    26. mpTimer->setInterval( 1000 );
    27. connect( mpTimer, &QTimer::timeout, this, &DigitalClock::onUpdateDateTime );
    28. mpTimer->start();
    29. }
    30.  
    31. DigitalClock::~DigitalClock()
    32. {
    33.  
    34. }
    35.  
    36. void DigitalClock::onUpdateDateTime()
    37. {
    38. QDateTime now = QDateTime::currentDateTime();
    39. QTime nowTime = now.time();
    40.  
    41. int hour = nowTime.hour();
    42. hour = ( hour <= 12 ? hour : hour - 12 );
    43. QString timeStr = QString( "%1:%2:%3" ).arg( hour, 2, 10, QChar(' ') ).arg( nowTime.minute(), 2, 10, QChar( '0' ) ).arg( nowTime.second(), 2, 10, QChar( '0' ) );
    44. mpTimeLabel->setText( timeStr );
    45.  
    46. QDate nowDate = now.date();
    47. QString dateStr = QString( "%1/%2/%3" ).arg( nowDate.day(), 2, 10, QChar( ' ' ) ).arg( nowDate.month(), 2, 10, QChar( '0' ) ).arg( nowDate.year(), 4 );
    48. mpDateLabel->setText( dateStr );
    49. }
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. #include "DigitalClock.h"
    2. #include <QApplication>
    3. #include <QMainWindow>
    4. #include <QStatusBar>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. QApplication a(argc, argv);
    9.  
    10.  
    11. DigitalClock * pClock = new DigitalClock( &w );
    12. QStatusBar * pBar = w.statusBar();
    13. pBar->addPermanentWidget( pClock );
    14.  
    15. w.show();
    16. return a.exec();
    17. }
    To copy to clipboard, switch view to plain text mode 
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Sep 2020
    Posts
    3
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android

    Default Re: Main Window Title Bar with Date / Clock

    Quote Originally Posted by d_stranz View Post
    Well, what else do you want it to do? The title is simply a string. If you want it to do something different, then write code to change the string you have stored and let it update the title the next time the timer fires.
    You are right. Thank you for your explanation and I fixed the issue now.

    If other parts of your app are also calling setWindowTitle for the main window, then that is no good because whatever they set the title to will change the next clock tick. This is why a clock in the status bar makes more sense - it is a standalone widget that doesn't change the behavior of anything else.
    I sure have appreciated this advice and will look into this as I will progress to learn more about Qt.

    Here is some code I wrote to make a digital clock with a transparent background that I can stick in a corner of my Desktop. All of the QSettings and mouse event stuff is just so I can have the clock appear in the same place on the screen after I move it, every time it starts up.
    Again, thank you and I will learn something from your code.

Similar Threads

  1. Replies: 2
    Last Post: 18th April 2017, 12:35
  2. Placing Clock on Title Bar
    By GG2013 in forum Newbie
    Replies: 2
    Last Post: 1st October 2013, 03:16
  3. cannot change main window title
    By marco.stanzani in forum Newbie
    Replies: 1
    Last Post: 3rd January 2013, 11:10
  4. Replies: 6
    Last Post: 8th May 2011, 18:52
  5. How to change computer's Clock and Date
    By anafor2004 in forum Newbie
    Replies: 1
    Last Post: 24th October 2009, 15:18

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.