qt中很少有时、分选择器,一般的做法都是用QComboBox下拉选择时间,但是在触摸屏中,使用QComboBox不怎么方便。现绘制一个时钟,通过按钮点击选择时、分。先上图:
里面的什么AM、PM、取消、保存可自行扩展,主要说明一下这个时钟是如何创建的。
创建数字1~12按钮代码:
//初始化界面
void GZNumber::initUI(QRect rect)
{
this->setGeometry(rect);
this->setObjectName("gz_number");
//通过stylesheet 设计背景为圆 主要通过border-radius: 150px, 150就是圆的半径
this->setStyleSheet("QWidget#gz_number{border-radius: 150px; background-color: #EEEEEE;}");
//创建中心确认按钮
m_BtnSave = new QPushButton(this);
auto _origin_x = (this->width() - 60) / 2;
auto _origin_y = (this->height() - 35) / 2;
m_BtnSave->setGeometry(_origin_x, _origin_y + 5, 60, 35);
m_BtnSave->setText("确认");
m_BtnSave->setStyleSheet(BTN_NORMAL_STYLE);
connect(m_BtnSave, &QPushButton::clicked, this, &GZNumber::slotBtnSave);
//时针长度
auto len = 124;
//创建数字按钮 通过计算圆的弧度获取每一个按钮的x,y坐标, 360/12= 30 每个角度为30度
//通过直角三角形计算坐标,如果有看不懂的同学,翻看初中的数学书理解下sin cos的计算
auto index = 1;
for(auto i = 1 ; i <= 12; i++){
auto btn = new QPushButton(this);
connect(btn, &QPushButton::clicked, this, &GZNumber::slotBtnClicked);
m_MapBtn[index] = btn;
auto x = qSin(i * 30 * pi /180) * len;
auto y = qCos(i * 30 * pi /180) * len;
x = this->width()/2 + x - BTN_SIZE / 2;
y = this->width()/2 - y - BTN_SIZE / 2;
btn->setGeometry(x,y, BTN_SIZE, BTN_SIZE);
btn->setStyleSheet(BTN_NUM_UNCLICK);
btn->setText(QString::number(index));
index++;
}
//默认先中 12点方向
auto btn12 = m_MapBtn[12];
btn12->clicked(true);
//btn12->setStyleSheet(BTN_NUM_CLICKED);
//m_ClickIndex = index-1;
//12点方向坐标 记录坐标 时针以比坐标为原点旋转角度,在paintEvent会用到
rect = btn12->geometry();
auto x = rect.x() + rect.width() / 2;
auto y = rect.y() + rect.height();
m_OriginRect = QRect(x - 1, y, LB_HANDLE_W,LB_HANDLE_H);
}
时针绘制:
void GZNumber::paintEvent(QPaintEvent *e)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
auto itr = m_MapBtn.find(m_ClickIndex);
if(itr != m_MapBtn.end()){
//根据12点方向旋转对应的角度,每次旋转30度
rotateAndPaintRect(&p, m_OriginRect, m_ClickIndex * 30);
this->update();
}
QWidget::paintEvent(e);
}
//旋转角度 在此不解释了, 百度下qt rotate的使用
void GZNumber::rotateAndPaintRect(QPainter *painter, const QRect &rect, int angle) {
QRect rotatedRect(-rect.width(), -rect.height(), rect.width(), rect.height());
int cx = rect.x() + rect.width();
int cy = rect.y() + rect.height();
painter->translate(cx, cy);
painter->rotate(angle);
painter->drawRect(rotatedRect);
painter->fillRect(rotatedRect, QColor(0,0,0));
}
资源地址:https://download.csdn.net/download/linkang1024/12292050
例子中,只需要关注GZNumber类如何实现即可, GZClock可自行扩展,在这里只抛个砖。能不能引玉就靠各位老铁了。