Calling all PySide python freaks

I’m starting to write my first flame centric PyQt app for flame. I’ve written a few Qt apps outside of flame but I’m having trouble getting a basic window to open and not crash from Flame. How does the event loop work n flame. Is flame the main loop or do I need to create my own with QApplication and then app.exec_, which if I do now I crash flame. All of my flame python relies heavily on homemade modules for repetitive stuff and all the menu a calls are done from a file per category. Mainmenu.py mediahub.py batch.py etc. these files reference my other modules to do their thing. I’m putting my first qt app into one of those modules and using other modules to setup defaults etc. Menu.py calls modules that have methods that builds the window. If I call on these modules outside of Flame everything works but from Flame… blammo. The method that is eventually called is a super class of QMainwindow that creates a QApplication if one doesn’t exist then eventually that gets app.exec_ at the end. I would think the exec would only get called once per session. I’m missing something obvious. Any ideas ?@MikeV @fredwarren you’re my only hope. Thanks.

3 Likes

You can do it like this:

class YourWindow(QtWidgets.QWidget):
    pass

To show this inside of Flame:

window = your_module.YourWindow()
window.show()

To show it outside of Flame:

if __name__ == "__main__":
	import sys
	import signal
	# make sure we can hit ctrl-c to exit the program
	signal.signal(signal.SIGINT, signal.SIG_DFL)
	# create and show the gui
	app = QtWidgets.QApplication(sys.argv)
	window = YourWindow()
	window.show()
	sys.exit(app.exec_())

Hey Miles!

I got a few grey hairs when I was first trying to figure this all out lol. You don’t need to use create your own QApplication or use app.exec_. From what I gather Flame is the QApplication and any UI you create is running on top of that. Fred could probably provide more insight on that. This is what I got to work for me to get a basic window to show up:

from PySide2 import QtCore, QtWidgets

window = QtWidgets.QWidget()
window.setMinimumSize(QtCore.QSize(950, 230))
window.setMaximumSize(QtCore.QSize(950, 230))
window.setWindowTitle('This is a window')
window.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.setStyleSheet('background-color: #313131')

# Center window in linux

resolution = QtWidgets.QDesktopWidget().screenGeometry()
window.move((resolution.width() / 2) - (window.frameSize().width() / 2),
            (resolution.height() / 2) - (window.frameSize().height() / 2))

window.show() 

Then I add my UI elements to that window.

To help make adding UI elements a little easier I’ve started creating classes for each of them. Not sure if this is the right way or the best way to be doing this, but it is making it more simple for me. So for adding QLabels I add this class to my script:

class FlameLabel(QtWidgets.QLabel):
    """
    Custom Qt Flame Label Widget
    Options for label type are normal, background, and outline
    """

    def __init__(self, label_name, parent, label_type='normal', *args, **kwargs):
        super(FlameLabel, self).__init__(*args, **kwargs)

        self.setText(label_name)
        self.setParent(parent)
        self.setMinimumSize(110, 28)
        self.setMaximumHeight(28)
        self.setFocusPolicy(QtCore.Qt.NoFocus)

        # Set label stylesheet based on label_type

        if label_type == 'normal':
            self.setStyleSheet('QLabel {color: #9a9a9a; border-bottom: 1px inset #282828; font: 14px "Discreet"}'
                               'QLabel:disabled {color: #6a6a6a}')
        elif label_type == 'background':
            self.setAlignment(QtCore.Qt.AlignCenter)
            self.setStyleSheet('color: #9a9a9a; background-color: #393939; font: 14px "Discreet"')
        elif label_type == 'outline':
            self.setAlignment(QtCore.Qt.AlignCenter)
            self.setStyleSheet('color: #9a9a9a; background-color: #212121; border: 1px solid #404040; font: 14px "Discreet"')

Then to add a labels to a window I simply add this line:

label = FlameLabel('Label Name', window, label_type='normal')

And in the case of the label, the label_type can be ‘normal’, ‘background’, and ‘outline’ to create the different looks of Flame’s label elements. I’ve created classes for a lot of Flames UI elements if you want them. I have a few of them posted here: Code — Flame Python Scripts I could get the rest of them posted this weekend if you’re interested.

2 Likes

@MikeV Those custom Flame-Like widgets are great! Thanks for sharing! I would really appreciate to see the rest. I was too lazy to rebuild them until now but also couldn’t find the Qt stylesheet Flame uses. I’m not even sure if it’s anywhere accessible or just somewhere in the compiled code (I guess the last one).

Any idea how to mimic the blue light of a button in Flame? (Don’t want to distract from the original topic. Sorry if this get’s to far away…)

Hey Claus

Thanks! I’ll try to get them all posted this weekend then. From what I understand Flame doesn’t use Qt for most of it’s UI so I don’t think there is a Qt stylesheet for it. I’ve just been building these from scratch.

This one will get you a Flame like push button with the blue on the right side of the button:

class FlamePushButton(QtWidgets.QPushButton):
“”"
Custom Qt Flame Push Button Widget
“”"

def __init__(self, button_name, checked, parent, *args, **kwargs):
    super(FlamePushButton, self).__init__(*args, **kwargs)

    self.setText(button_name)
    self.setParent(parent)
    self.setCheckable(True)
    self.setChecked(checked)
    self.setMinimumSize(110, 28)
    self.setMaximumSize(110, 28)
    self.setFocusPolicy(QtCore.Qt.NoFocus)
    self.setStyleSheet('QPushButton {color: #9a9a9a; background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: .90 #424142, stop: .91 #2e3b48); text-align: left; border-top: 1px inset #555555; border-bottom: 1px inset black; font: 14px "Discreet"}'
                       'QPushButton:checked {color: #d9d9d9; background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: .90 #4f4f4f, stop: .91 #5a7fb4); font: italic; border: 1px inset black; border-bottom: 1px inset #404040; border-right: 1px inset #404040}'
                       'QPushButton:disabled {color: #6a6a6a; background-color: qlineargradient(x1: 0, y1: 0, x2: 1, y2: 0, stop: .90 #383838, stop: .91 #353535); font: light; border-top: 1px solid #575757; border-bottom: 1px solid #242424; border-right: 1px solid #353535; border-left: 1px solid #353535}'
                       'QToolTip {color: black; background-color: #ffffde; border: black solid 1px}')

To add buttons to your window you would then add this:

pushbutton = FlamePushButton(’ Button Name’, True, window)

Where it says True, that sets whether the button is checked or not. So it should be a True or False value.

Thanks guys. I was doing what @MikeV was doing, elements the same way, but making the window from within a function that I’ll at some point want in a class metho. which doesn’t work and I don’t understand why.

def make_window(self):
window = QWidget()
window.setMinimumSize(QSize(950, 230))
window.setWindowTitle(‘title’)
window.setWindowFlags(Qt.WindowStaysOnTopHint)
window.setAttribute(Qt.WA_DeleteOnClose)
window.move(500, 500)
label = FlameLabel(‘Label Name’, window, label_type=‘normal’)

    window.show()
1 Like

Yea… I’ve had this problem in before as well when putting a window within a function. I have no idea what the problem is. Usually when I start having this problem I just take one of my old scripts that has it working delete everything except the lines that build the window as use that as a base to start the new script. I would love to know why this happens. I’m guessing its probably something simple that I’m overlooking.

Thanks for your time Mike. Keep up the great work. @fredwarren how bout some love mate. Any clues to our problems ?

I love this thread. Thank you so much, guys!

Sorry if I haven’t been as responsive lately. We are in the last stretch of the upcoming 2022 release and I do not have much time for anything else these days. I should be able to look into this sooner than later. I’ll come back to you.

5 Likes

@miles I think the problem is, that the window instance get’s destroyed immediately once the function is run through and therefore doesn’t show (or better: does not keep showing). Once the scope of this function ends, there is no reference to the window left and it’s picked up by the garbage collector.
To avoid this simply return the window from your function and it will show.

@MikeV Just found the time to have a look at the coloured button! Thanks a lot for sharing, that looks great! :slight_smile:

1 Like

Hello my name is Miles great to meet you @claussteinmassl . That did it mate. Thank you ! I was totally stumped. Such a simple solution. Thanks again and happy Friday ! -M

2 Likes

Hey Miles, glad it worked for you, too! Happy weekend! :slight_smile:

2 Likes

@claussteinmassl you are an instant Logik Legend!

3 Likes

haha, thanks mate! :smiley:

adding my 2 cents, I find it easier to have a separate stylesheet that does only that, then import it in hooks that indeed also import sets of custom made widgets.
This way you can have different stylesheet sets and switch if you want to (skins?)
Edit: or easily update all UIs at once if anything changes in the futur.

1 Like