2

Backgroud: I play Grand Strategy Games a lot. Part of addcition comes out of AARs (After Action Reports). Stories players write about games. Ofc. that require save games cause "quick" game is longer than 10 hours.

Problem: Game do not support automatic save games other than 3 autosaves that get overridden every time. So I want to write app that will use Qt for tracking file changes. Every time game auto saves, this app will rename and move to choosen location savegame. But since its full screen game, players may forgot to turn on my app I need way to indicate state of my app.

Question: How can I make 2D overlay over portion of full screen 3D app, given that I use Python and Qt?

Alternative I do not think that sound warnings would solve my problem, since it would work if someone forgotten to choose save game to track, but it would not work if someone completely forgot to turn on my app. While lack of icon would be enough to inform about such mistake.

But if you can find any other way to indicate that my app is not turned on or configured, post your ideas in answers.

przemo_li
  • 3,932
  • 4
  • 35
  • 60

1 Answers1

0

Very old post, but I will let this reply here for others looking for something similar.

Check PyWinCtl. If you are able to build a frameless, semi-transparent window using Python and Qt, alwaysOnTop(True) and acceptInput(False) methods will make the trick, but only with games based on CGI calls, not if they use DirectDraw Exclusive Mode (for this, I'm also searching for a Python solution, this is why I ended here!)

In the meantime, you can try this on Qt when initializing your window (it's a piece of code, not reproduceble, sorry):

# Make it transparent to input
self.setFocusPolicy(QtCore.Qt.NoFocus)
if "Linux" in platform.platform():
    self.setAttribute(QtCore.Qt.WA_X11DoNotAcceptFocus, True)
self.setAttribute(QtCore.Qt.WA_TransparentForMouseEvents, True)
self.setAttribute(QtCore.Qt.WA_InputMethodTransparent, True)
self.setAttribute(QtCore.Qt.WA_ShowWithoutActivating, True)

# Make it semi-transparent
self.setWindowOpacity(128)

# Setting flags: on top, frameless and no focus
self.setWindowFlags(QtCore.Qt.Tool| QtCore.Qt.CustomizeWindowHint | QtCore.Qt.WindowStaysOnTopHint | QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowDoesNotAcceptFocus)

I think the name of the functions and parameters are self-explicative (let me know if they are not).

The part of making your window transparent to input methods is important, otherwise the window can be eventually clicked and the game will lose focus. This effect on the window is permanent.

The part of making your window semi-transparent will not work as is. You need to implement a custom paintEvent for your window, like this (again, not reproducible, sorry):

def paintEvent(self, event=None):
    # This is required to draw a semi-transparent window
    # https://stackoverflow.com/questions/33982167/pyqt5-create-semi-transparent-window-with-non-transparent-children
    painter = QtGui.QPainter(self)
    painter.setOpacity(0.4)  # or your desired opacity level
    painter.setBrush(QtCore.Qt.black)  # or your desired background color
    painter.setPen(QtGui.QPenQtCore.Qt.black))  # or your desired background color
    painter.drawRect(self.rect())

The part of making it always on top might not be permanent, this is why using pywinctl's alwaysOnTop() is recommended, furthermore, it's better to recall it, for instance every second, to bring your window back to top in case it's obscured by any reason.

Kalma
  • 111
  • 2
  • 15