Update dxvk settings,to use new overlay settings
This commit is contained in:
parent
d1df48e837
commit
cc92322d43
|
@ -357,7 +357,7 @@ class GameSettings(QWidget, Ui_GameSettings):
|
|||
|
||||
class LinuxAppSettings(LinuxSettings):
|
||||
def __init__(self):
|
||||
super(LinuxAppSettings, self).__init__("app")
|
||||
super(LinuxAppSettings, self).__init__()
|
||||
|
||||
def update_game(self, app_name):
|
||||
self.name = app_name
|
||||
|
@ -365,4 +365,4 @@ class LinuxAppSettings(LinuxSettings):
|
|||
self.wine_exec.setText(self.load_setting(self.name, "wine_executable"))
|
||||
|
||||
self.dxvk.name = app_name
|
||||
self.dxvk.load_settings()
|
||||
self.dxvk.load_settings(self.name)
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
from logging import getLogger
|
||||
|
||||
from PyQt5.QtWidgets import QGroupBox
|
||||
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.ui.components.tabs.settings.dxvk import Ui_DxvkSettings
|
||||
|
||||
logger = getLogger("DXVK Settings")
|
||||
|
||||
|
||||
class DxvkSettings(QGroupBox, Ui_DxvkSettings):
|
||||
def __init__(self, name=None):
|
||||
super(DxvkSettings, self).__init__()
|
||||
self.setupUi(self)
|
||||
|
||||
self.name = name if name is not None else "default"
|
||||
self.core = LegendaryCoreSingleton()
|
||||
|
||||
self.dxvk_options_map = {
|
||||
"devinfo": self.devinfo,
|
||||
"fps": self.fps,
|
||||
"frametime": self.frametime,
|
||||
"memory": self.memory,
|
||||
"gpuload": self.gpuload,
|
||||
"version": self.version,
|
||||
"api": self.api,
|
||||
}
|
||||
|
||||
self.load_settings()
|
||||
self.show_dxvk.currentIndexChanged.connect(self.store_settings)
|
||||
for opt in self.dxvk_options_map:
|
||||
self.dxvk_options_map[opt].stateChanged.connect(self.store_settings)
|
||||
|
||||
# Show HUD ComboBox
|
||||
# System Default, index 0, removes DXVK_HUD to use setting from env
|
||||
# Hidden , index 1, adds DXVK_HUD=0 to override system configuration
|
||||
# Visible , index 2, adds DXVK_HUD=1 to override system configuration
|
||||
# Custom Options, index 3, adds DXVK_HUD=devinfo,fps and enables the customization panel
|
||||
|
||||
def load_settings(self):
|
||||
dxvk_options = self.core.lgd.config.get(
|
||||
f"{self.name}.env", "DXVK_HUD", fallback=None
|
||||
)
|
||||
self.gb_dxvk_options.setDisabled(True)
|
||||
if dxvk_options is not None:
|
||||
if dxvk_options == "0":
|
||||
self.show_dxvk.setCurrentIndex(1)
|
||||
return
|
||||
elif dxvk_options == "1":
|
||||
self.show_dxvk.setCurrentIndex(2)
|
||||
return
|
||||
else:
|
||||
self.show_dxvk.setCurrentIndex(3)
|
||||
self.gb_dxvk_options.setDisabled(False)
|
||||
for opt in dxvk_options.split(","):
|
||||
try:
|
||||
self.dxvk_options_map[opt].setChecked(True)
|
||||
except KeyError:
|
||||
print(f"Malformed DXVK Option: {opt}")
|
||||
continue
|
||||
else:
|
||||
self.show_dxvk.setCurrentIndex(0)
|
||||
|
||||
def store_settings(self):
|
||||
show_dxvk_index = self.show_dxvk.currentIndex()
|
||||
if show_dxvk_index:
|
||||
if f"{self.name}.env" not in self.core.lgd.config.sections():
|
||||
self.core.lgd.config.add_section(f"{self.name}.env")
|
||||
if show_dxvk_index == 1:
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = "0"
|
||||
if show_dxvk_index == 2:
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = "1"
|
||||
if show_dxvk_index == 3:
|
||||
dxvk_options = []
|
||||
for opt in self.dxvk_options_map:
|
||||
if self.dxvk_options_map[opt].isChecked():
|
||||
dxvk_options.append(opt)
|
||||
if not dxvk_options:
|
||||
# Check if this is the first activation
|
||||
stored = self.core.lgd.config.get(
|
||||
f"{self.name}.env", "DXVK_HUD", fallback=None
|
||||
)
|
||||
if stored not in [None, "0", "1"]:
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = "0"
|
||||
else:
|
||||
dxvk_options = ["devinfo", "fps"]
|
||||
# Check again if dxvk_options changed due to first activation
|
||||
if dxvk_options:
|
||||
self.core.lgd.config[f"{self.name}.env"]["DXVK_HUD"] = ",".join(
|
||||
dxvk_options
|
||||
)
|
||||
else:
|
||||
if (
|
||||
self.core.lgd.config.get(f"{self.name}.env", "DXVK_HUD", fallback=None)
|
||||
is not None
|
||||
):
|
||||
self.core.lgd.config.remove_option(f"{self.name}.env", "DXVK_HUD")
|
||||
if not self.core.lgd.config[f"{self.name}.env"]:
|
||||
self.core.lgd.config.remove_section(f"{self.name}.env")
|
||||
self.core.lgd.save_config()
|
||||
self.load_settings()
|
|
@ -3,8 +3,9 @@ from logging import getLogger
|
|||
|
||||
from PyQt5.QtWidgets import QFileDialog, QWidget
|
||||
|
||||
from rare.components.tabs.settings.settings_widgets.dxvk import DxvkSettings
|
||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton
|
||||
from rare.components.tabs.settings.dxvk import DxvkSettings
|
||||
|
||||
from rare.ui.components.tabs.settings.linux import Ui_LinuxSettings
|
||||
from rare.utils.extra_widgets import PathEdit
|
||||
|
||||
|
@ -42,7 +43,7 @@ class LinuxSettings(QWidget, Ui_LinuxSettings):
|
|||
self.exec_layout.addWidget(self.wine_exec)
|
||||
|
||||
# dxvk
|
||||
self.dxvk = DxvkSettings(self.name)
|
||||
self.dxvk = DxvkSettings()
|
||||
self.overlay_layout.addWidget(self.dxvk)
|
||||
|
||||
def load_prefix(self) -> str:
|
||||
|
|
25
rare/components/tabs/settings/settings_widgets/dxvk.py
Normal file
25
rare/components/tabs/settings/settings_widgets/dxvk.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
from PyQt5.QtCore import QCoreApplication
|
||||
|
||||
from .overlay_settings import OverlaySettings, CustomOption
|
||||
|
||||
|
||||
class DxvkSettings(OverlaySettings):
|
||||
def __init__(self):
|
||||
super(DxvkSettings, self).__init__(
|
||||
[
|
||||
("fps", QCoreApplication.translate("DxvkSettings", "FPS")),
|
||||
("frametime", QCoreApplication.translate("DxvkSettings", "Frametime")),
|
||||
("memory", QCoreApplication.translate("DxvkSettings", "Memory usage")),
|
||||
("gpuload", QCoreApplication.translate("DxvkSettings", "GPU usage")),
|
||||
("devinfo", QCoreApplication.translate("DxvkSettings", "Show Device info")),
|
||||
("version", QCoreApplication.translate("DxvkSettings", "DXVK Version")),
|
||||
("api", QCoreApplication.translate("DxvkSettings", "D3D feature level")),
|
||||
],
|
||||
[
|
||||
(CustomOption.number_input("scale", 1, True), QCoreApplication.translate("DxvkSettings", "Scale"))
|
||||
],
|
||||
"DXVK_HUD", "0"
|
||||
)
|
||||
|
||||
self.setTitle(self.tr("DXVK Settings"))
|
||||
self.gb_options.setTitle(self.tr("Custom options"))
|
|
@ -0,0 +1,182 @@
|
|||
from enum import Enum
|
||||
from logging import getLogger
|
||||
from typing import List, Dict, Tuple, Any, Callable
|
||||
|
||||
from PyQt5.QtGui import QIntValidator, QDoubleValidator
|
||||
from PyQt5.QtWidgets import QGroupBox, QCheckBox, QWidget, QLineEdit, QLabel, QComboBox
|
||||
|
||||
from rare import shared
|
||||
from rare.shared import LegendaryCoreSingleton
|
||||
from rare.ui.components.tabs.settings.overlay import Ui_OverlaySettings
|
||||
from rare.utils import config_helper
|
||||
|
||||
logger = getLogger("Overlay")
|
||||
|
||||
|
||||
class TextInputField(QLineEdit):
|
||||
def __init__(self):
|
||||
super(TextInputField, self).__init__()
|
||||
self.value_changed = self.textChanged
|
||||
self.set_value = self.setText
|
||||
self.set_default = lambda: self.setText("")
|
||||
|
||||
def get_value(self):
|
||||
return self.text()
|
||||
|
||||
|
||||
class ComboBox(QComboBox):
|
||||
def __init__(self):
|
||||
super(ComboBox, self).__init__()
|
||||
self.value_changed = self.currentIndexChanged
|
||||
self.get_value = self.currentText
|
||||
self.set_value = self.setCurrentText
|
||||
self.set_default = lambda: self.setCurrentIndex(0)
|
||||
|
||||
|
||||
class CustomOption:
|
||||
input_field: QWidget
|
||||
var_name: str
|
||||
|
||||
@classmethod
|
||||
def string_input(cls, var_name: str, placeholder: str):
|
||||
tmp = cls()
|
||||
tmp.input_field = TextInputField()
|
||||
tmp.var_name = var_name
|
||||
tmp.input_field.setPlaceholderText(placeholder)
|
||||
return tmp
|
||||
|
||||
@classmethod
|
||||
def number_input(cls, var_name: str, placeholder: Any, is_float: bool = False):
|
||||
tmp = cls()
|
||||
tmp.input_field = TextInputField()
|
||||
tmp.var_name = var_name
|
||||
tmp.input_field.setPlaceholderText(str(placeholder))
|
||||
if is_float:
|
||||
validator = QDoubleValidator()
|
||||
else:
|
||||
validator = QIntValidator()
|
||||
tmp.input_field.setValidator(validator)
|
||||
return tmp
|
||||
|
||||
@classmethod
|
||||
def select_input(cls, var_name: str, options: List[str]):
|
||||
"""options: default value in options[0]"""
|
||||
tmp = cls()
|
||||
tmp.input_field = ComboBox()
|
||||
tmp.var_name = var_name
|
||||
tmp.input_field.addItems(options)
|
||||
return tmp
|
||||
|
||||
|
||||
class ActivationStates(Enum):
|
||||
DEFAULT = 0
|
||||
HIDDEN = 1
|
||||
ACTIVATED = 2
|
||||
|
||||
|
||||
class OverlaySettings(QGroupBox, Ui_OverlaySettings):
|
||||
name: str = "default"
|
||||
settings_updatable = True
|
||||
|
||||
def __init__(self, checkboxes_map: List[Tuple[str, str]], value_map: List[Tuple[CustomOption, str]],
|
||||
config_env_var_name: str, no_display_value: str,
|
||||
set_activation_state: Callable[[Enum], None] = lambda x: None):
|
||||
super(OverlaySettings, self).__init__()
|
||||
self.setupUi(self)
|
||||
self.core = LegendaryCoreSingleton()
|
||||
self.config_env_var_name = config_env_var_name
|
||||
self.no_display_value = no_display_value
|
||||
self.set_activation_state = set_activation_state
|
||||
|
||||
self.checkboxes: Dict[str, QCheckBox] = {}
|
||||
|
||||
for i, (var_name, translated_text) in enumerate(checkboxes_map):
|
||||
cb = QCheckBox(translated_text)
|
||||
self.options_grid.addWidget(cb, i // 4, i % 4)
|
||||
self.checkboxes[var_name] = cb
|
||||
cb.stateChanged.connect(self.update_settings)
|
||||
|
||||
self.values: Dict[str, QWidget] = {}
|
||||
|
||||
num_rows = len(checkboxes_map) // 4
|
||||
for custom_option, translated_text in value_map:
|
||||
input_field = custom_option.input_field
|
||||
self.options_form.addRow(QLabel(translated_text), input_field)
|
||||
self.values[custom_option.var_name] = input_field
|
||||
input_field.value_changed.connect(self.update_settings)
|
||||
num_rows += 1
|
||||
|
||||
self.show_overlay_combo.currentIndexChanged.connect(self.update_settings)
|
||||
|
||||
def update_settings(self):
|
||||
if not self.settings_updatable:
|
||||
return
|
||||
if self.show_overlay_combo.currentIndex() == 0:
|
||||
# System default
|
||||
config_helper.remove_option(f"{self.name}.env", self.config_env_var_name)
|
||||
self.gb_options.setDisabled(True)
|
||||
self.set_activation_state(ActivationStates.DEFAULT)
|
||||
return
|
||||
|
||||
elif self.show_overlay_combo.currentIndex() == 1:
|
||||
# hidden
|
||||
config_helper.add_option(f"{self.name}.env", self.config_env_var_name, self.no_display_value)
|
||||
self.gb_options.setDisabled(True)
|
||||
self.set_activation_state(ActivationStates.HIDDEN)
|
||||
return
|
||||
elif self.show_overlay_combo.currentIndex() == 2:
|
||||
self.gb_options.setDisabled(False)
|
||||
# custom options
|
||||
var_names = []
|
||||
for var_name, cb in self.checkboxes.items():
|
||||
if cb.isChecked():
|
||||
var_names.append(var_name)
|
||||
|
||||
for var_name, input_field in self.values.items():
|
||||
text = input_field.get_value()
|
||||
if text not in ["default", ""]:
|
||||
var_names.append(f"{var_name}={text}")
|
||||
|
||||
if not var_names:
|
||||
list(self.checkboxes.values())[0].setChecked(True)
|
||||
var_names.append(list(self.checkboxes.keys())[0])
|
||||
|
||||
config_helper.add_option(f"{self.name}.env", self.config_env_var_name, ",".join(var_names))
|
||||
self.set_activation_state(ActivationStates.ACTIVATED)
|
||||
|
||||
def load_settings(self, name: str):
|
||||
self.settings_updatable = False
|
||||
# load game specific
|
||||
self.name = name
|
||||
|
||||
for checkbox in self.checkboxes.values():
|
||||
checkbox.setChecked(False)
|
||||
for input_field in self.values.values():
|
||||
input_field.set_default()
|
||||
|
||||
options = self.core.lgd.config.get(f"{self.name}.env", self.config_env_var_name, fallback=None)
|
||||
if options is None:
|
||||
logger.debug(f"No Overlay settings found {self.config_env_var_name}")
|
||||
self.show_overlay_combo.setCurrentIndex(0)
|
||||
self.gb_options.setDisabled(True)
|
||||
|
||||
elif options == self.no_display_value:
|
||||
# not visible
|
||||
self.gb_options.setDisabled(True)
|
||||
self.show_overlay_combo.setCurrentIndex(1)
|
||||
|
||||
else:
|
||||
self.show_overlay_combo.setCurrentIndex(2)
|
||||
for option in options.split(","):
|
||||
try:
|
||||
if "=" in option:
|
||||
var_name, value = option.split("=")
|
||||
self.values.get(var_name).set_value(value)
|
||||
else:
|
||||
self.checkboxes.get(option).setChecked(True)
|
||||
except Exception as e:
|
||||
logger.warning(e)
|
||||
|
||||
self.gb_options.setDisabled(False)
|
||||
|
||||
self.settings_updatable = True
|
|
@ -45,7 +45,7 @@ class WrapperSettings(QGroupBox, Ui_WrapperSettings):
|
|||
super(WrapperSettings, self).__init__("Wrapper")
|
||||
self.setupUi(self)
|
||||
self.widgets.setLayout(FlowLayout())
|
||||
self.core = shared.core
|
||||
self.core = shared.LegendaryCoreSingleton()
|
||||
|
||||
self.add_button.clicked.connect(self.add_button_pressed)
|
||||
|
||||
|
|
74
rare/ui/components/tabs/settings/overlay.py
Normal file
74
rare/ui/components/tabs/settings/overlay.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/settings/overlay.ui'
|
||||
#
|
||||
# Created by: PyQt5 UI code generator 5.15.6
|
||||
#
|
||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_OverlaySettings(object):
|
||||
def setupUi(self, OverlaySettings):
|
||||
OverlaySettings.setObjectName("OverlaySettings")
|
||||
OverlaySettings.resize(555, 188)
|
||||
OverlaySettings.setWindowTitle("Overlay Settings")
|
||||
OverlaySettings.setTitle("")
|
||||
self.dxvk_layout = QtWidgets.QGridLayout(OverlaySettings)
|
||||
self.dxvk_layout.setObjectName("dxvk_layout")
|
||||
self.lbl_show_overlay = QtWidgets.QLabel(OverlaySettings)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.lbl_show_overlay.sizePolicy().hasHeightForWidth())
|
||||
self.lbl_show_overlay.setSizePolicy(sizePolicy)
|
||||
self.lbl_show_overlay.setObjectName("lbl_show_overlay")
|
||||
self.dxvk_layout.addWidget(self.lbl_show_overlay, 0, 0, 1, 1)
|
||||
self.show_overlay_combo = QtWidgets.QComboBox(OverlaySettings)
|
||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.show_overlay_combo.sizePolicy().hasHeightForWidth())
|
||||
self.show_overlay_combo.setSizePolicy(sizePolicy)
|
||||
self.show_overlay_combo.setObjectName("show_overlay_combo")
|
||||
self.show_overlay_combo.addItem("")
|
||||
self.show_overlay_combo.addItem("")
|
||||
self.show_overlay_combo.addItem("")
|
||||
self.dxvk_layout.addWidget(self.show_overlay_combo, 0, 1, 1, 2)
|
||||
self.gb_options = QtWidgets.QGroupBox(OverlaySettings)
|
||||
self.gb_options.setTitle("")
|
||||
self.gb_options.setObjectName("gb_options")
|
||||
self.gridLayout = QtWidgets.QGridLayout(self.gb_options)
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.options_form = QtWidgets.QFormLayout()
|
||||
self.options_form.setObjectName("options_form")
|
||||
self.gridLayout.addLayout(self.options_form, 1, 0, 1, 1)
|
||||
self.options_grid = QtWidgets.QGridLayout()
|
||||
self.options_grid.setObjectName("options_grid")
|
||||
self.gridLayout.addLayout(self.options_grid, 0, 0, 1, 1)
|
||||
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
self.gridLayout.addItem(spacerItem, 0, 1, 2, 1)
|
||||
self.dxvk_layout.addWidget(self.gb_options, 2, 0, 1, 3)
|
||||
|
||||
self.retranslateUi(OverlaySettings)
|
||||
QtCore.QMetaObject.connectSlotsByName(OverlaySettings)
|
||||
|
||||
def retranslateUi(self, OverlaySettings):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
self.lbl_show_overlay.setText(_translate("OverlaySettings", "Show HUD"))
|
||||
self.show_overlay_combo.setItemText(0, _translate("OverlaySettings", "System Default"))
|
||||
self.show_overlay_combo.setItemText(1, _translate("OverlaySettings", "Hidden"))
|
||||
self.show_overlay_combo.setItemText(2, _translate("OverlaySettings", "Visible"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
OverlaySettings = QtWidgets.QGroupBox()
|
||||
ui = Ui_OverlaySettings()
|
||||
ui.setupUi(OverlaySettings)
|
||||
OverlaySettings.show()
|
||||
sys.exit(app.exec_())
|
90
rare/ui/components/tabs/settings/overlay.ui
Normal file
90
rare/ui/components/tabs/settings/overlay.ui
Normal file
|
@ -0,0 +1,90 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>OverlaySettings</class>
|
||||
<widget class="QGroupBox" name="OverlaySettings">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>555</width>
|
||||
<height>188</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Overlay Settings</string>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="dxvk_layout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="lbl_show_overlay">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show HUD</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="show_overlay_combo">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>System Default</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Hidden</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Visible</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<widget class="QGroupBox" name="gb_options">
|
||||
<property name="title">
|
||||
<string/>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<layout class="QFormLayout" name="options_form"/>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="options_grid"/>
|
||||
</item>
|
||||
<item row="0" column="1" rowspan="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in a new issue