weiekko 发表于 2023-4-11 13:09

MoneyProgress_win Qt 学习过程记录

本帖最后由 weiekko 于 2023-4-11 13:09 编辑

## 起因

前段时间分享了一个MoneyProgress的Mac软件,一直有人在论坛发帖问有没有win版的,恰好最近在看Qt,于是就有了这个项目.

写这个贴子的目的是为了记录一下开发过程,以及遇到的问题.

以后可以拿它做参考,也可以给有需要的人提供一些帮助.

MAC版的项目地址: (https://github.com/Lakr233/MoneyProgress)
WIN版的项目地址: (https://github.com/wxydejoy/MoneyProgress_win)

程序很大程度参考了原作者的UI设计,这里再次感谢原作者.

## 开发环境

- Windows 10 20H2(这个不是很重要)
- Qt 5.15 with Mingw(这个很重要)


## 开发过程

这块看我的(https://github.com/wxydejoy/MoneyProgress_win/commits/main)记录就行了,虽然有点乱,但是基本上都是有用的.

这里只记录一些比较重要的问题,其他的问题可以参考(https://doc.qt.io/qt-5/index.html)

多看文档,多看文档,多看文档.


### 问题1: 图片过大

原作者的图片都是png格式,大小足足有3.27MB,分辨率为1024x1024,应该是自己画的吧.

刚开始导入图片设置为`label`设置样式表`background-image: url(:/img/avatar.png);`

是这样的:


可以看到图片很大,很奇怪,

解决办法:

**设置为`border-image: url(:/img/avatar.png);`**


这样它就会自动缩放了.可以通过设置`label`的`width`和`height`来控制图片的大小.



### 问题2: 无法获取到正确的屏幕分辨率

这个问题是论坛上有人提出来的,我也遇到了.

原代码为:

```cpp
// 这里省略了一些代码
// 获取屏幕分辨率高度
QApplication::desktop()->width();


```

实际获取的不一定就是当前屏幕的分辨率,有时候会获取到错误的值.
比如你有多块屏幕,它会获取到所有屏幕的分辨率的和.就很离谱.
这就会导致我们的程序在不同的屏幕上显示的效果不一样.
任务栏的弹窗就奇奇怪怪的.甚至看不到.

解决办法:

```cpp
// 这里省略了一些代码
QApplication::screenAt(QCursor().pos())->geometry().width()


```
意为获取鼠标所在屏幕的分辨率宽度.非常ok.


### 问题3: 文本无法正常更新

问题代码:

因为我想实现每次点击任务栏图标都会弹出一个弹窗,显示当前的挣钱进度,所以我在`MoneyProgress`类中添加了一个`IconMessage`类的对象(一个小widget),并且在`MoneyProgress`类中添加了一个`update`函数,用来更新弹窗中的文本.
同时`update`还要负责更新主窗口中的文本.所以就有了如下代码



```cpp

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;
    }
}

```
可以看到大致思路就是判断两个界面是否可见,如果可见就更新文本.但是任务栏那个小窗口的文本无法更新,调试发现了一个低级错误

```cpp

update(); //错误的写法
iconmessage.show();
// update(); 把update()放在这里就可以更新了

```

确实很低级



### 问题4: QSettings 无效

这个问题是在保存时间的时候遇到的,我想把设置保存到`QSettings`里面,但是发现无论怎么设置都无效.
在网上逛了半天,发现是因为`QSettings`只能在构造函数和析构函数中使用,不能在其他函数中使用.

问题代码:

```cpp
//原本设计的是每次设置改变就保存一次,但是发现无效
void MoneyProgress::on_timeSleepdown_userTimeChanged(const QTime &time)
{
    // 这里省略了一些代码 settings 是一个QSettings对象,在.h文件中定义
    settings.setValue("sleepDown", sleepDown);
   
    // 保存设置

}

```

解决办法:


将`QSettings`的保存设置放到析构函数中,这样就可以正常使用了.
```cpp


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`属性就可以了.

问题代码:

```css
QWidget {
    background-color: rgb(255, 255, 255);
    border-width: 3px;
    border-color: rgba(255, 216, 58, 225);
    border-radius: 15px;
}
```
解决方法
   
```css
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的缩放功能,而是使用系统的缩放功能
```ini
WindowsArguments = dpiawareness=0
```

具体看这个(https://github.com/wxydejoy/MoneyProgress_win/commit/76ce3656f6f45008369d1b023bd450f817b59ab3)

### 问题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()`可以获取鼠标所在屏幕的分辨率宽度等等.


最后希望大家能够多多支持,如果有什么问题,欢迎指正,可以在评论区留言,我会尽快回复的.
页: [1]
查看完整版本: MoneyProgress_win Qt 学习过程记录