起因
前段时间分享了一个MoneyProgress的Mac软件,一直有人在论坛发帖问有没有win版的,恰好最近在看Qt,于是就有了这个项目.
写这个贴子的目的是为了记录一下开发过程,以及遇到的问题.
以后可以拿它做参考,也可以给有需要的人提供一些帮助.
MAC版的项目地址: MoneyProgress
WIN版的项目地址: MoneyProgress_win
程序很大程度参考了原作者的UI设计,这里再次感谢原作者.
开发环境
- Windows 10 20H2(这个不是很重要)
- Qt 5.15 with Mingw(这个很重要)
开发过程
这块看我的commit记录就行了,虽然有点乱,但是基本上都是有用的.
这里只记录一些比较重要的问题,其他的问题可以参考Qt官方文档
多看文档,多看文档,多看文档.
问题1: 图片过大
原作者的图片都是png格式,大小足足有3.27MB,分辨率为1024x1024,应该是自己画的吧.
刚开始导入图片设置为label
设置样式表background-image: url(:/img/avatar.png);
是这样的:
可以看到图片很大,很奇怪,
解决办法:
设置为border-image: url(:/img/avatar.png);
这样它就会自动缩放了.可以通过设置label
的width
和height
来控制图片的大小.
问题2: 无法获取到正确的屏幕分辨率
这个问题是论坛上有人提出来的,我也遇到了.
原代码为:
// 这里省略了一些代码
// 获取屏幕分辨率高度
QApplication::desktop()->width();
实际获取的不一定就是当前屏幕的分辨率,有时候会获取到错误的值.
比如你有多块屏幕,它会获取到所有屏幕的分辨率的和.就很离谱.
这就会导致我们的程序在不同的屏幕上显示的效果不一样.
任务栏的弹窗就奇奇怪怪的.甚至看不到.
解决办法:
// 这里省略了一些代码
QApplication::screenAt(QCursor().pos())->geometry().width()
意为获取鼠标所在屏幕的分辨率宽度.非常ok.
问题3: 文本无法正常更新
问题代码:
因为我想实现每次点击任务栏图标都会弹出一个弹窗,显示当前的挣钱进度,所以我在MoneyProgress
类中添加了一个IconMessage
类的对象(一个小widget),并且在MoneyProgress
类中添加了一个update
函数,用来更新弹窗中的文本.
同时update
还要负责更新主窗口中的文本.所以就有了如下代码
void MoneyProgress::update()
{
// 这里省略了一些代码
// 判断两个界面是否可见
if (this->isVisible())
{
ui->labelMoneyNow->setText("您当前已经挣了"+QString::number(moneyday*progress/1000,'f',1)+"元;");
ui->labelDay->setText("您一月工作" + QString::number(days) + "天;");
ui->labelMoneyDay->setText("您一天能挣" + QString::number(moneyday, 'f', 1) + "元;");
ui->labelHourDay->setText("您一天工作" + QString::number(hours, 'f', 1) + "小时;");
ui->labelMoneySecond->setText("您一秒钟能挣" + QString::number(moneysecond, 'f', 6) + "元;");
}
if (iconmessage.isVisible())
{
iconmessage.update(progress, moneyday);
qDebug() << progress;
}
}
可以看到大致思路就是判断两个界面是否可见,如果可见就更新文本.但是任务栏那个小窗口的文本无法更新,调试发现了一个低级错误
update(); //错误的写法
iconmessage.show();
// update(); 把update()放在这里就可以更新了
确实很低级
问题4: QSettings 无效
这个问题是在保存时间的时候遇到的,我想把设置保存到QSettings
里面,但是发现无论怎么设置都无效.
在网上逛了半天,发现是因为QSettings
只能在构造函数和析构函数中使用,不能在其他函数中使用.
问题代码:
//原本设计的是每次设置改变就保存一次,但是发现无效
void MoneyProgress::on_timeSleepdown_userTimeChanged(const QTime &time)
{
// 这里省略了一些代码 settings 是一个QSettings对象,在.h文件中定义
settings.setValue("sleepDown", sleepDown);
// 保存设置
}
解决办法:
将QSettings
的保存设置放到析构函数中,这样就可以正常使用了.
MoneyProgress::~MoneyProgress()
{
QSettings settings("MuYin", "MoneyProgress_win");
// 保存设置
settings.setValue("money", money);
settings.setValue("days", days);
settings.setValue("workUp", workUp);
settings.setValue("workDown", workDown);
settings.setValue("sleepUp", sleepUp);
settings.setValue("sleepDown", sleepDown);
// settings.setValue("geometry", this->saveGeometry());
// settings.setValue("windowState", this->saveState());
// 保存设置
settings.sync();
delete ui;
}
问题5: QSS样式表不会用
因为我设置了标题栏隐藏
this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); // 隐藏标题栏
所以一直弄不出来borde
的样式,最后发现改centralwidget
的border
属性就可以了.
问题代码:
QWidget {
background-color: rgb(255, 255, 255);
border-width: 3px;
border-color: rgba(255, 216, 58, 225);
border-radius: 15px;
}
解决方法
QWidget {
background-color: rgb(255, 255, 255);
border-color: rgba(255, 216, 58, 225);
border-radius: 15px;
}
QWidget#centralwidget {
background-color: rgb(255, 255, 255);
border: 3px solid #ffee6f;
/* border-color: rgba(255, 216, 58, 225); */
}
css还是不太了解,回头需要好好学习一下.
问题6: 程序整体缩放问题
引用网友的话:
Qt下高分屏的问题,几乎是一场灾难。希望未来 Qt 能有更好的解决方案。
解决方法: 添加 qt/etc/qt.conf
文件,注意这是在qrc文件中的路径,它的完整路径是qrc:/qt/etc/qt.conf
,网上说一定不要弄错
文件内容的意思为不使用QT的缩放功能,而是使用系统的缩放功能
WindowsArguments = dpiawareness=0
具体看这个commit
问题7: QtCreator 无法Debug
将build模式从release改为debug就可以了..................................
总结
项目不大,时间也不算长,大概两三个晚上的样子,但是在这个过程中学到了很多东西,比如说QSettings
的使用,QSS
的使用,QTimer
的使用,QApplication::screenAt(QCursor().pos())->geometry().width()
的使用,以及一些小技巧,比如说QSettings
只能在构造函数和析构函数中使用,QSS
的border
属性要写在centralwidget
上,QTimer
的start
函数可以传入一个参数,表示延迟多久开始计时,QApplication::screenAt(QCursor().pos())->geometry().width()
可以获取鼠标所在屏幕的分辨率宽度等等.
最后希望大家能够多多支持,如果有什么问题,欢迎指正,可以在评论区留言,我会尽快回复的.