前言

  最近折腾 Unreal Python 工具开发,又遇到了一些问题。
  工具开发经常需要提供一些弹窗来提示用户。
  但是因为 Unreal 的 Qt 环境和 Maya 之类的纯 Qt 软件有很大的出入,所以是不能互相兼容的。

QMessageBox 的优化

  这就导致过去常用的 QMessageBox.warning 的操作方式不太可行。
  因为有时候需要在完全没有 Qt 窗口的环境下弹出窗口。
  后面我发现可以即便没有运行的 QWidget 也可以通过 QApplication.desktop() 的方式获取 Widget 来依附, 所以原先的方式还是可以用的。
  缺点就是没有通过我封装的 show 进行触发,窗口是独立于 Unreal 的。

  所以基于上面的原因还是不可避免需要重写一下 MessageBox 弹出的效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import unreal
from Qt import QtCore, QtWidgets, QtGui
from dayu_widgets import dayu_theme

def alert(msg=u"msg", title=u"警告", icon=QtWidgets.QMessageBox.Warning, button_text=u"确定"):
# NOTE 生成 Qt 警告窗口
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(icon)
msg_box.setWindowTitle(title)
msg_box.setText(msg)
msg_box.addButton(button_text, QtWidgets.QMessageBox.AcceptRole)
unreal.parent_external_window_to_slate(msg_box.winId())
dayu_theme.apply(msg_box)
msg_box.exec_()

  我可以通过全手动的方式实现 QMessageBox ,这样可控性更高。
  通过 exec_ 函数实现 Qt 事件的占用,确保用户关闭窗口才能控制引擎。

无输入 优化

  上面的实现效果已经不错了,但是还是不太完美。
  这种弹窗依然需要用户进行操作才可以将窗口关闭。
  如果窗口可以自动关闭就好了~

  我查了一下 Qt 的功能,发现 其实 Qt 自带有 alert 函数可以实现定时关闭的效果 链接
  但是我简单测试了一下,这个函数完全不起作用,无论是 PySide 还是 PySide2 都是(:з」∠)
  希望有人能帮我解答一下这个问题。


  虽然 Qt 默认内置的操作没法实现上面提到的提示弹出自动消失的效果。
  不过强大的 dayu_widgets 已经封装好了相关的组件,用起来很方便。
  比如 dayu_widgets 提供的 MToast 案例

alt

  但是同时也遇到了相关的问题,Unreal Python 不存在运行中的窗口,怎么才可以确保 MToast 在当前屏幕的中央触发呢?
  经过我的研究,可以活用 QDesktopWidget 获取当前鼠标所在的 屏幕,从而实现 MToast 居中显示的操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

toast_dict = {
"error": MToast.error,
"info": MToast.info,
"success": MToast.success,
"warning": MToast.warning,
}

def toast(text="", typ=""):
# NOTE 获取鼠标的位置弹出屏幕居中的 MToast 警告
global MESSAGE_TOAST
# MOTE 获取鼠标位置
pos = QtGui.QCursor.pos()
desktop = QtWidgets.QApplication.desktop()
# MOTE 生成一个临时的屏幕 Widget
MESSAGE_TOAST = QtWidgets.QWidget()
# MOTE 将屏幕的长宽赋予到临时 Widget 上
MESSAGE_TOAST.setGeometry(desktop.screenGeometry(pos))
toast_dict.get(typ,MToast.error)(parent=MESSAGE_TOAST, text=text)

  上面的录屏是我两个显示屏,在不同屏幕上的弹出提示效果。
  如此以来我就可以根据用户的屏幕弹出提示信息,更加人性化,而且这个操作不依赖于激活的窗口,交互体验很好。

总结

  最近又折腾了很多 Unreal C++ 结合 Python 操作的东西。
  越是折腾,越是深刻体会到 C++ 开发的痛苦,虽然运行效率很高,但是开发效率真的很低。
  每次编译需要几十秒,项目的引擎还没法做到官方直播的视频里面开着引擎热更新。
  编译完之后还重新开引擎,如果不重开反正也会报错强制重开(:з」∠)
  以前 Python 遇到代码的崩溃循环的时候,我已经非常抓狂了,但是试错的效率还是很高的。
  今天遇到了 C++ 代码的崩溃循环,耗了一天啥也没干就没了o(╥﹏╥)o