Пример #1
0
#!/usr/bin/env python3
import sys
from Qt.QtWidgets import QApplication, QWidget

if __name__ == '__main__':

    app = QApplication(sys.argv)

    w = QWidget()
    w.resize(250, 150)
    w.move(300, 300)
    w.setWindowTitle('Logan')
    w.show()

    sys.exit(app.exec_())
Пример #2
0
class CSSEditor:
    """
    Make sure to instanciate *after* creating the top level widgets of your QApplication
    """
    def __init__(self, project_name):
        self.project_name = project_name
        self._app = QApplication.instance()
        self._css_filepath = None

        self.main_window = QWidget()
        self.main_window.setWindowFlags(Qt.Tool)
        self.main_window.setWindowTitle("CSS Editor - " + self.project_name)

        self.variables = Variables()
        self.variables.changed.connect(self._variables_changed)
        self.variables.changed.connect(self._render_and_apply)

        self.template = CSSTextEdit()
        self.template.changed.connect(self._template_changed)
        self.template.changed.connect(self._render_and_apply)

        self.save = QPushButton('Save stylesheet to')
        self.save.clicked.connect(self._save_stylesheet)

        self.save_destination = QLineEdit()
        self.save_destination.textChanged.connect(self._destination_changed)

        self.splitter = QSplitter()
        self.splitter.setOrientation(Qt.Vertical)
        self.splitter.addWidget(self.variables)
        self.splitter.addWidget(self.template)

        layout = QGridLayout(self.main_window)
        layout.addWidget(self.splitter, 0, 0, 1, 2)
        layout.addWidget(self.save, 1, 0)
        layout.addWidget(self.save_destination, 1, 1)

        self.main_window.resize(800, 600)

        self._project_dir = self._ensure_project_dir()
        self._top_level_widgets = [
            widget for widget in QApplication.topLevelWidgets() if
            widget.windowTitle() != self.main_window.windowTitle()
        ]
        self._variables = dict()
        self._template = None
        self._stylesheet = ""

        self._app.aboutToQuit.connect(self._save_editor_state)
        self._open()
        self.save_destination.setText(self.css_filepath)
        self.main_window.show()

    @property
    def css_filepath(self):
        if self._css_filepath is None:
            return self._project_dir + self.project_name + '.css'

        return self._css_filepath

    def _ensure_project_dir(self):
        dir_ = os.path.expanduser('~/CSSEditor/' + self.project_name + '/')
        if not os.path.isdir(dir_):
            os.makedirs(dir_)

        return dir_

    def _open(self):
        self.variables.blockSignals(True)
        self.template.blockSignals(True)

        try:
            with open(self._project_dir + EDITOR_STATE, 'r') as qsseditor_file:
                qsseditor = json.load(qsseditor_file)
                WindowPosition.restore(self.main_window, qsseditor['window'])
                self.splitter.setSizes(qsseditor['splitter'])
                self._css_filepath = qsseditor.get('save_destination', self.css_filepath)
                self.save_destination.setText(self._css_filepath)

            with open(self._project_dir + THEME_VARIABLES, 'r') as f_variables:
                self.variables.variables = json.load(f_variables)

            with open(self._project_dir + THEME_TEMPLATE, 'r') as f_template:
                self.template.set_plain_text(f_template.read())
        except Exception as e:
            pass
        self.variables.blockSignals(False)
        self.template.blockSignals(False)

        self._template_changed()
        self._variables_changed()
        self._render_and_apply()

    def _destination_changed(self):
        self._css_filepath = self.save_destination.text()
        self._save_editor_state()

    def _save_editor_state(self):
        with open(self._project_dir + EDITOR_STATE, 'w+') as f_qsseditor:
            json.dump({
                'window': WindowPosition.save(self.main_window),
                'splitter': self.splitter.sizes(),
                'save_destination': self.css_filepath
            }, f_qsseditor)

    def _template_changed(self):
        template = self.template.plain_text()
        with open(self._project_dir + THEME_TEMPLATE, 'w+') as f_template:
            f_template.write(template)

        try:
            self._template = jinja2.Template(template)
        except TemplateSyntaxError:
            pass

    def _variables_changed(self):
        with open(self._project_dir + THEME_VARIABLES, 'w+') as f_variables:
            f_variables.write(json.dumps(self.variables.variables, indent=2))

        self._variables = dict()

        for variable_name, variable_value in self.variables.variables.items():
            if isinstance(variable_value, list) and len(variable_value) == 3:
                self._variables[variable_name] = 'rgb({})'.format(', '.join([str(channel) for channel in variable_value]))

                for variant in COLOR_VARIANTS:
                    channels = [str(int(channel * variant * 0.01)) for channel in variable_value]
                    self._variables['{}{:02d}'.format(variable_name, variant)] = 'rgb({})'.format(', '.join(channels))

            else:
                self._variables[variable_name] = variable_value

    def _apply_style(self, style):
        for widget in self._top_level_widgets:
            widget.setStyleSheet(style)

    def _render_and_apply(self):
        self._apply_style("")

        if self._template is None:
            return

        self._stylesheet = self._template.render(**self._variables)
        self._apply_style(self._stylesheet)

    def _save_stylesheet(self):
        stylesheet = [
            "/* GUI Bedos - CSS Template */",
            "/****************************/",
            "",
            "/* VARIABLES",
            json.dumps(self.variables.variables, indent=2),
            "/****************************/",
            "",
            "/* TEMPLATE",
            self.template.plain_text().replace('*/', '*|'),
            "/****************************/",
            "",
            "/* ACTUAL CSS */",
            "",
            self._stylesheet
        ]
        with open(self.css_filepath, 'w+') as f_stylesheet:
            f_stylesheet.write('\n'.join(stylesheet))