반응형
done
- 메뉴바 없앰 -> QCoreApplication 에서 QWidget으로 변경
- 윈도우에서 프로그램이 최상위 상단에 있도록 -> ok Qt::WindowStayOnTopHint
- pause 동작, pause후에 start재개 -> flag로 count up, start버튼 눌렀을 때 이미 생성된 thread있는지 체크
TBD
- 버튼 hide상태이다가 마우스가 위에 올라올 때만 show
- 마우스 클릭에 따라 프로그램 이동
main.cpp
timer.cpp timer.h timer.ui
clockthread.cpp clockthread.h
main.cpp
#include "timer.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
timer w;
w.show();
return a.exec();
}
timer.cpp
#include "timer.h"
/**
*/
timer::timer(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setWindowFlags(Qt::Widget | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setParent(0); // Create toplevel widget -> ?
setAttribute(Qt::WA_NoSystemBackground, true);
// 위젯이 배경이 없는 것을 나타낸다.
// 위젯이 paint Event를 받을 때, 배경이 자동적으로 다시 그려지지 않는다.
// WA_OpaquePaintEvent와는 다르게, 새로 노출된 부분이 절대 배경으로 채워지지 않는다.
// WA_OpaquePaintEvent : 윈도우가 처음에 보여진 이후에, 프로그램이 paint event를 동작시킬 때까지 이것을 통해 user는 볼 수 있다.
setAttribute(Qt::WA_TranslucentBackground, true);
// 위젯이 투명한 배경을 가져야만 한다.
// 위젯의 불투명하지 않은 부분이 투명해진다. 왜냐하면 위젯이 alpha 채널을 가지고 잇기 때문이다.
// WA_TranslucentBackground 플래그를 셋팅하는 것은 WA_NoSystemBackground를 셋팅하도록 만든다.
// 또한 윈도우에서 실행되는 프로그램이라면 Qt::FramelessWindowHint 플래그도 설정해야한다.
setAttribute(Qt::WA_PaintOnScreen);
ui.label->setText("0 : 0 : 0");
setFixedSize(600,240);
connect(&m_clockThread, SIGNAL(sendTime(QString)), ui.label, SLOT(setText(QString)), Qt::QueuedConnection);
connect(this, SIGNAL(resume()), &m_clockThread, SLOT(onResume()));
connect(this, SIGNAL(reset()), &m_clockThread, SLOT(onReset()) );
connect(this, SIGNAL(pause()), &m_clockThread, SLOT(onPause()) );
}
/**
*/
void timer::on_closeButton_clicked()
{
//ui.label->setText("clicked closeButton");
m_clockThread.quit();
QCoreApplication::quit();
}
/**
*/
void timer::on_startButton_clicked()
{
//ui.label->setText("clicked startButton");
if (m_clockThread.isRunning())
{
emit resume();
}
else
{
m_clockThread.start();
}
}
/**
*/
void timer::on_pauseButton_clicked()
{
//ui.label->setText("clicked pauseButton");
//m_clockThread.wait(); // 파라미터 ULONG_MAX 줘야하는건지?
emit pause();
}
/**
*/
void timer::on_resetButton_clicked()
{
//ui.label->setText("clicked resetButton");
emit reset();
}
timer.h
#pragma once
#ifndef TIMER_H
#define TIMER_H
#include "clockthread.h"
#include <QtWidgets/QMainWindow>
#include "ui_timer.h"
class ClockThread;
class timer : public QWidget
{
Q_OBJECT
public:
timer(QWidget *parent = Q_NULLPTR);
private:
Ui::timer ui;
ClockThread m_clockThread;
signals:
void resume();
void pause();
void reset();
private slots:
void on_closeButton_clicked();
void on_startButton_clicked();
void on_pauseButton_clicked();
void on_resetButton_clicked();
};
#endif
timer.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>timer</class>
<widget class="QWidget" name="timer">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>464</width>
<height>165</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="2" column="0">
<widget class="QPushButton" name="startButton">
<property name="text">
<string>start</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="pauseButton">
<property name="text">
<string>pause</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QPushButton" name="resetButton">
<property name="text">
<string>reset</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="3">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="font">
<font>
<family>Arial Black</family>
<pointsize>50</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string notr="true">0 : 0 : 0</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="closeButton">
<property name="text">
<string>close</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
clockthread.h
#ifndef CLOCKTHREAD_H
#define CLOCKTHREAD_H
#include <QThread>
#include <QObject>
class ClockThread : public QThread
{
Q_OBJECT;
public:
ClockThread(QObject* parent=Q_NULLPTR);
virtual ~ClockThread();
private:
bool m_firstTime;
bool m_running;
int m_hours;
int m_minutes;
int m_seconds;
private:
void init();
void run();
signals:
void sendTime(QString time);
private slots:
void onResume();
void onPause();
void onReset();
void timerHit();
};
#endif
clockthread.cpp
#include "clockthread.h"
#include <QTimer>
ClockThread::ClockThread(QObject* parent)
: QThread(parent)
{
init();
}
ClockThread::~ClockThread()
{
}
void ClockThread::init()
{
m_running = false;
m_hours = 0;
m_minutes = 0;
m_seconds = 0;
QString time = QString("%1 : %2 : %3").arg(m_hours).arg(m_minutes).arg(m_seconds);
emit sendTime(time);
}
void ClockThread::onResume()
{
m_running = true;
}
void ClockThread::onPause()
{
m_running = false;
}
void ClockThread::onReset()
{
init();
quit();
}
void ClockThread::run()
{
m_running = true;
QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(timerHit()), Qt::DirectConnection);
timer.setInterval(1000); // 1000msc = 1 sec
timer.start();
exec();
}
void ClockThread::timerHit()
{
if(m_running)
{
m_seconds++;
if(m_seconds>60)
{
m_minutes++;
m_seconds = 0;
}
if(m_minutes>60)
{
m_hours++;
m_minutes = 0;
}
QString time = QString("%1 : %2 : %3").arg(m_hours).arg(m_minutes).arg(m_seconds);
emit sendTime(time);
}
}
반응형