def __init__(self, ftrack_entity, hint=None): '''Instantiate asset selector with *ftrack_entity*.''' super(AssetSelector, self).__init__() self.assets = ftrack_entity.session.query( 'select name, id, type_id from Asset where context_id ' 'is "{0}"'.format( ftrack_entity['id'] ) ).all() main_layout = QtWidgets.QVBoxLayout(self) self.setLayout(main_layout) main_layout.setContentsMargins(0, 0, 0, 0) self.asset_selector = QtWidgets.QComboBox(self) main_layout.addWidget(self.asset_selector) self.asset_selector.addItem('Create new asset') for asset in self.assets: self.asset_selector.addItem(asset['name']) self.asset_name = QtWidgets.QLineEdit(self) self.asset_name.setPlaceholderText('Asset name...') main_layout.addWidget(self.asset_name) self.asset_type_selector = QtWidgets.QComboBox(self) self.asset_types = ftrack_entity.session.query( 'select name, short, id from AssetType' ).all() for asset_type in self.asset_types: self.asset_type_selector.addItem(asset_type['name']) # automatically set the correct asset type if hint: for index, asset_type in enumerate(self.asset_types): if asset_type['short'] == hint: self.asset_type_selector.setCurrentIndex(index) break main_layout.addWidget(self.asset_type_selector) self.asset_selector.currentIndexChanged.connect( self._on_asset_selection_changed ) self.asset_type_selector.currentIndexChanged.connect( self.notify_changed ) self.asset_name.textChanged.connect(self.notify_changed)
def __init__(self, *args, **kwargs): '''Instantiate the entity selector widget.''' super(EntitySelector, self).__init__(*args, **kwargs) self._entity = None # Create widget used to select an entity. selectionWidget = QtWidgets.QFrame() selectionWidget.setLayout(QtWidgets.QHBoxLayout()) selectionWidget.layout().setContentsMargins(0, 0, 0, 0) self.insertWidget(0, selectionWidget) self.entityBrowser = _entity_browser.EntityBrowser(parent=self) self.entityBrowser.setMinimumSize(600, 400) self.entityBrowser.selectionChanged.connect( self._onEntityBrowserSelectionChanged) self.entityBrowseButton = QtWidgets.QPushButton('Browse') # TODO: Once the link is available through the API change this to a # combo with assigned tasks. self.assignedContextSelector = QtWidgets.QLineEdit() self.assignedContextSelector.setReadOnly(True) selectionWidget.layout().addWidget(self.assignedContextSelector) selectionWidget.layout().addWidget(self.entityBrowseButton) # Create widget used to present current selection. presentationWidget = QtWidgets.QFrame() presentationWidget.setLayout(QtWidgets.QHBoxLayout()) presentationWidget.layout().setContentsMargins(0, 0, 0, 0) self.insertWidget(1, presentationWidget) self.entityPath = _entity_path.EntityPath() presentationWidget.layout().addWidget(self.entityPath) self.discardEntityButton = QtWidgets.QPushButton() removeIcon = QtGui.QIcon(QtGui.QPixmap(':/ftrack/image/light/remove')) self.discardEntityButton.setIconSize(QtCore.QSize(20, 20)) self.discardEntityButton.setIcon(removeIcon) self.discardEntityButton.setFixedWidth(20) self.discardEntityButton.clicked.connect( self._onDiscardEntityButtonClicked) presentationWidget.layout().addWidget(self.discardEntityButton) self.entityChanged.connect(self.entityPath.setEntity) self.entityChanged.connect(self._updateIndex) self.entityBrowseButton.clicked.connect( self._onEntityBrowseButtonClicked)
def __init__(self, results): '''Instantiate and show results.''' super(Dialog, self).__init__() self.setObjectName('ftrack-result-dialog') self.setMinimumSize(1080, 720) main_layout = QtWidgets.QVBoxLayout(self) self.setLayout(main_layout) filter_layout = QtWidgets.QHBoxLayout() filter_label = QtWidgets.QLabel('Filter log') self.filter_field = QtWidgets.QLineEdit() self.filter_field.setObjectName('ftrack-log-filter-field') self.filter_field.textChanged.connect(self.on_search) filter_layout.addWidget(filter_label) filter_layout.addWidget(self.filter_field) main_layout.addLayout(filter_layout) log_list = QtWidgets.QTableView() log_list.verticalHeader().hide() log_list.setObjectName('ftrack-log-view') log_list.setAlternatingRowColors(True) log_list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) log_list.horizontalHeader().setStretchLastSection(True) log_items = self._parse_results(results) log_model = ftrack_connect_pipeline.ui.model.log_table.LogTableModel( self, log_items) self.log_sort_model = ftrack_connect_pipeline.ui.model.log_table.FilterProxyModel( ) self.log_sort_model.setDynamicSortFilter(True) self.log_sort_model.setSourceModel(log_model) log_list.setModel(self.log_sort_model) main_layout.addWidget(log_list) open_log_folder_button = QtWidgets.QPushButton('Open log directory') open_log_folder_button.clicked.connect(self._on_logging_button_clicked) main_layout.addWidget(open_log_folder_button)
def setupUi(self, ExportOptions): ExportOptions.setObjectName("ExportOptions") ExportOptions.resize(339, 266) sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth( ExportOptions.sizePolicy().hasHeightForWidth()) ExportOptions.setSizePolicy(sizePolicy) self.verticalLayout = QtWidgets.QVBoxLayout(ExportOptions) self.verticalLayout.setSpacing(3) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.optionsPlaceHolderLayout = QtWidgets.QHBoxLayout() self.optionsPlaceHolderLayout.setObjectName("optionsPlaceHolderLayout") self.verticalLayout.addLayout(self.optionsPlaceHolderLayout) self.label_4 = QtWidgets.QLabel(ExportOptions) self.label_4.setObjectName("label_4") self.verticalLayout.addWidget(self.label_4) self.gridLayout_4 = QtWidgets.QGridLayout() self.gridLayout_4.setObjectName("gridLayout_4") self.thumbnailLineEdit = QtWidgets.QLineEdit(ExportOptions) self.thumbnailLineEdit.setObjectName("thumbnailLineEdit") self.gridLayout_4.addWidget(self.thumbnailLineEdit, 2, 0, 1, 1) self.pushButton = QtWidgets.QPushButton(ExportOptions) self.pushButton.setObjectName("pushButton") self.gridLayout_4.addWidget(self.pushButton, 2, 1, 1, 1) self.screenshotButton = QtWidgets.QPushButton(ExportOptions) self.screenshotButton.setObjectName("screenshotButton") self.gridLayout_4.addWidget(self.screenshotButton, 2, 2, 1, 1) self.verticalLayout.addLayout(self.gridLayout_4) self.label_5 = QtWidgets.QLabel(ExportOptions) self.label_5.setObjectName("label_5") self.verticalLayout.addWidget(self.label_5) self.commentTextEdit = QtWidgets.QPlainTextEdit(ExportOptions) self.commentTextEdit.setMaximumSize(QtCore.QSize(16777215, 80)) self.commentTextEdit.setObjectName("commentTextEdit") self.verticalLayout.addWidget(self.commentTextEdit) self.publishButton = QtWidgets.QPushButton(ExportOptions) self.publishButton.setObjectName("publishButton") self.verticalLayout.addWidget(self.publishButton) self.progressBar = QtWidgets.QProgressBar(ExportOptions) self.progressBar.setProperty("value", 24) self.progressBar.setObjectName("progressBar") self.verticalLayout.addWidget(self.progressBar) self.publishMessageLabel = QtWidgets.QLabel(ExportOptions) self.publishMessageLabel.setText("") self.publishMessageLabel.setObjectName("publishMessageLabel") self.verticalLayout.addWidget(self.publishMessageLabel) spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) self.verticalLayout.addItem(spacerItem) self.retranslateUi(ExportOptions) QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), ExportOptions.setThumbnailFilename) QtCore.QObject.connect(self.screenshotButton, QtCore.SIGNAL("clicked()"), ExportOptions.takeScreenshot) QtCore.QMetaObject.connectSlotsByName(ExportOptions)
def __init__(self, data_dict, options): '''Instanstiate settings from *options*.''' super(ActionSettingsWidget, self).__init__() self.setLayout(QtWidgets.QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) for option in options: type_ = option['type'] label = option.get('label', '') name = option['name'] value = option.get('value') empty_text = option.get('empty_text') if name in data_dict.get('options', {}): value = data_dict['options'][name] if value is not None and name not in data_dict: # Set default value from options. data_dict[name] = value field = None if type_ == 'group': nested_dict = data_dict[name] = dict() settings_widget = QtWidgets.QGroupBox(label) settings_widget.setLayout(QtWidgets.QVBoxLayout()) settings_widget.layout().addWidget( ActionSettingsWidget(nested_dict, option.get('options', []))) self.layout().addRow(settings_widget) if type_ == 'boolean': field = QtWidgets.QCheckBox() if value is True: field.setCheckState(QtCore.Qt.Checked) field.stateChanged.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda check_box: (check_box.checkState() == QtCore.Qt. CheckState.Checked))) if type_ == 'textarea': field = textarea.TextAreaField(empty_text or '') if value is not None: field.setPlainText(unicode(value)) field.value_changed.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda textarea_widget: textarea_widget.value())) if type_ == 'text': field = QtWidgets.QLineEdit() if value is not None: field.insert(unicode(value)) field.textChanged.connect( functools.partial(self.update_on_change, data_dict, field, name, lambda line_edit: line_edit.text())) if type_ == 'number': field = QtWidgets.QDoubleSpinBox() if value is not None: field.setValue(float(value)) field.setMaximum(sys.maxint) field.setMinimum(-sys.maxint) field.valueChanged.connect( functools.partial(self.update_on_change, data_dict, field, name, lambda spin_box: spin_box.value())) if type_ == 'enumerator': field = QtWidgets.QComboBox() for item in option['data']: field.addItem(item['label']) field.currentIndexChanged.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda box: (option['data'][box.currentIndex()]['value']))) if type_ == 'qt_widget': field = option['widget'] field.value_changed.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda custom_field: (custom_field.value()))) if field is not None: if label: label_widget = QtWidgets.QLabel(label) self.layout().addRow(label_widget, field) else: self.layout().addRow(field)
def __init__(self, parent=None, session=None, context=None): super(BuildAssetTrackDialog, self).__init__(parent) self.setWindowTitle("Build Track") if not session: session = FnAssetAPI.SessionManager.currentSession() self.__session = session if not context: context = session.createContext() self.__context = context self.__selection = [] self.__entities = [] self.__ignoreClips = False self.__lastIgnoreClips = None self.__lastParentRef = None layout = QtWidgets.QVBoxLayout() self.setLayout(layout) # Asset Manager Widget self.__relationshipWidget = session.getManagerWidget( kWorkflowRelationshipWidgetId, args=[context,]) layout.addWidget(self.__relationshipWidget) # Stretch layout.addStretch() # Options optionsBox = QtWidgets.QGroupBox("Options") optionsLayout = QtWidgets.QVBoxLayout() optionsBox.setLayout(optionsLayout) layout.addWidget(optionsBox) self.__trackName = QtWidgets.QLineEdit() trackNameLayout = QtWidgets.QHBoxLayout() trackNameLayout.addWidget(QtWidgets.QLabel("Track Name")) trackNameLayout.addWidget(self.__trackName) optionsLayout.addLayout(trackNameLayout) self.__useClipsRadio = QtWidgets.QRadioButton("Match by Clip") self.__useShotsRadio = QtWidgets.QRadioButton("Match by Shot") optionsLayout.addWidget(self.__useClipsRadio) optionsLayout.addWidget(self.__useShotsRadio) ## @todo Use the project entityReferences Parent if we have one? context.access = context.kReadMultiple context.retention = context.kTransient specification = specifications.ShotSpecification() self.__shotParentPicker = self.__session.getManagerWidget( FnAssetAPI.ui.constants.kInlinePickerWidgetId, args=[specification, context]) optionsLayout.addWidget(self.__shotParentPicker) # Buttons ## @todo disable the ok button if using shots and no valid entity ref self.__buttons = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) self.__buttons.button(QtWidgets.QDialogButtonBox.Ok).setText('Build') layout.addWidget(self.__buttons) # Connections self.__buttons.accepted.connect(self.accept) self.__buttons.rejected.connect(self.reject) self.__useShotsRadio.toggled.connect(self.__modeChanged) self.__useClipsRadio.toggled.connect(self.__modeChanged) self.__relationshipWidget.criteriaChanged.connect(self.__syncUI) # This might be better on editingFinished, but there is only one text field # some of the time so loosing focus might not happen as required self.__trackName.textChanged.connect(self.__syncUI) self.__shotParentPicker.selectionChanged.connect(self.__parentChanged) self.__syncUI() # Make sure the name field is ready for editing as we can't create without self.__trackName.setFocus()
def __init__(self, selection, parent=None): ''' Initialise class with *selection* and *parent* widget. ''' self._result_data = {} if not parent: parent = hiero.ui.mainWindow() super(FtrackReBuildServerTrackDialog, self).__init__(parent) self.logger = logging.getLogger(__name__ + '.' + self.__class__.__name__) num_tasks = registry.numTasks() self._ftrack_tasks = [ registry.taskName(index) for index in range(num_tasks) ] self._selection = selection if self._selection: self.project = self.item_project(self._selection[0]) self._window_title = 'Build track from ftrack' self.setWindowTitle(self._window_title) # self.setWindowIcon(QtGui.QPixmap(':ftrack/image/default/ftrackLogoColor')) self.setSizeGripEnabled(True) layout = QtWidgets.QVBoxLayout() formLayout = QtWidgets.QFormLayout() self._tracknameField = QtWidgets.QLineEdit() self._tracknameField.setToolTip('Name of new track') formLayout.addRow('Track name:', self._tracknameField) self.tasks_combobox = QtWidgets.QComboBox() formLayout.addRow('Task type:', self.tasks_combobox) self.asset_type_combobox = QtWidgets.QComboBox() formLayout.addRow('Asset type:', self.asset_type_combobox) self.asset_status_combobox = QtWidgets.QComboBox() formLayout.addRow('Asset Status:', self.asset_status_combobox) self.component_combobox = QtWidgets.QComboBox() formLayout.addRow('Component name:', self.component_combobox) layout.addLayout(formLayout) # Add the standard ok/cancel buttons, default to ok. self._buttonbox = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.StandardButton.Ok | QtWidgets.QDialogButtonBox.StandardButton.Cancel) self._buttonbox.button( QtWidgets.QDialogButtonBox.StandardButton.Ok).setText('Build') self._buttonbox.button( QtWidgets.QDialogButtonBox.StandardButton.Ok).setDisabled(True) self._buttonbox.button( QtWidgets.QDialogButtonBox.StandardButton.Ok).setAutoDefault(True) self._buttonbox.accepted.connect(self.accept_test) self._buttonbox.rejected.connect(self.reject) layout.addWidget(self._buttonbox) self.setLayout(layout) # populate data self.populate_tasks() self.populate_asset_types() self.populate_components() self.populate_asset_statuses() # connect signals self.tasks_combobox.currentIndexChanged.connect(self.get_components) self.asset_type_combobox.currentIndexChanged.connect( self.get_components) self.component_combobox.currentIndexChanged.connect( self.get_components) self.asset_status_combobox.currentIndexChanged.connect( self.get_components) # set suggested track name self._tracknameField.setText(self.suggested_track_name) # force ui to refresh self.get_components()
def parseOptions(self, rowLayout, optionElements, assetTypeName, enabled): '''Parse options.''' optionsCount = 0 for k in range(optionElements.length()): optionElement = optionElements.item(k).toElement() optionType = optionElement.attribute('type') optionValue = optionElement.attribute('value') if optionValue == 'True': optionValue = True elif optionValue == 'False': optionValue = False optionName = optionElement.attribute('name') self.stackedOptions[assetTypeName].append(optionName) if optionType == 'float': floatBox = QtWidgets.QDoubleSpinBox() floatBox.setEnabled(enabled) floatBox.setObjectName(optionName) floatBox.setSingleStep(0.1) floatBox.setMaximum(sys.maxint) floatBox.setMinimum(-sys.maxint) floatBox.setValue(float(optionValue)) rowLayout.addWidget(floatBox) optionsCount = 1 if optionType == 'checkbox': checkBox = QtWidgets.QCheckBox() checkBox.setEnabled(enabled) checkBox.setChecked(bool(optionValue)) checkBox.setObjectName(optionName) rowLayout.addWidget(checkBox) optionsCount = 1 if optionType == 'string': textBox = QtWidgets.QLineEdit() textBox.setEnabled(enabled) textBox.setText(optionValue) textBox.setObjectName(optionName) rowLayout.addWidget(textBox) optionsCount = 1 if optionType == 'combo': comboBox = QtWidgets.QComboBox() comboBox.setEnabled(enabled) optionitemElements = optionElement.elementsByTagName( 'optionitem') for t in range(optionitemElements.length()): optionitemElement = optionitemElements.item(t).toElement() optionitemValue = optionitemElement.attribute('name') comboBox.addItem(optionitemValue) comboBox.setObjectName(optionName) rowLayout.addWidget(comboBox) optionsCount = optionitemElements.length() if optionType == 'radio': radioWidget = QtWidgets.QWidget() radioLayout = QtWidgets.QVBoxLayout() radioLayout.setSpacing(1) radioWidget.setLayout(radioLayout) optionitemElements = optionElement.elementsByTagName( 'optionitem') for t in range(optionitemElements.length()): optionitemElement = optionitemElements.item(t).toElement() optionitemValue = optionitemElement.attribute('value') optionitemName = optionitemElement.attribute('name') radioButton = QtWidgets.QRadioButton(optionitemName) if bool(optionitemValue): radioButton.setChecked(True) radioLayout.addWidget(radioButton) radioButton.setEnabled(enabled) radioButton.setObjectName(optionName) rowLayout.addWidget(radioWidget) optionsCount = optionitemElements.length() return optionsCount
def setupUi(self, ExportAssetOptions): ExportAssetOptions.setObjectName("ExportAssetOptions") ExportAssetOptions.resize(429, 130) self.verticalLayout = QtWidgets.QVBoxLayout(ExportAssetOptions) self.verticalLayout.setSpacing(3) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setObjectName("verticalLayout") self.gridLayout = QtWidgets.QGridLayout() self.gridLayout.setObjectName("gridLayout") self.assetTaskLabel = QtWidgets.QLabel(ExportAssetOptions) self.assetTaskLabel.setMinimumSize(QtCore.QSize(120, 0)) self.assetTaskLabel.setMaximumSize(QtCore.QSize(120, 16777215)) self.assetTaskLabel.setObjectName("assetTaskLabel") self.gridLayout.addWidget(self.assetTaskLabel, 1, 0, 1, 1) self.ListAssetsComboBox = QtWidgets.QComboBox(ExportAssetOptions) self.ListAssetsComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.ListAssetsComboBox.setMaximumSize(QtCore.QSize(200, 16777215)) self.ListAssetsComboBox.setObjectName("ListAssetsComboBox") self.gridLayout.addWidget(self.ListAssetsComboBox, 0, 1, 1, 1) self.ListAssetNamesComboBox = QtWidgets.QComboBox(ExportAssetOptions) self.ListAssetNamesComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.ListAssetNamesComboBox.setMaximumSize(QtCore.QSize(200, 16777215)) self.ListAssetNamesComboBox.setObjectName("ListAssetNamesComboBox") self.gridLayout.addWidget(self.ListAssetNamesComboBox, 3, 1, 1, 1) self.AssetNameLineEdit = QtWidgets.QLineEdit(ExportAssetOptions) self.AssetNameLineEdit.setEnabled(True) self.AssetNameLineEdit.setMinimumSize(QtCore.QSize(100, 0)) self.AssetNameLineEdit.setMaximumSize(QtCore.QSize(200, 16777215)) self.AssetNameLineEdit.setObjectName("AssetNameLineEdit") self.gridLayout.addWidget(self.AssetNameLineEdit, 4, 1, 1, 1) self.AssetTaskComboBox = QtWidgets.QComboBox(ExportAssetOptions) self.AssetTaskComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.AssetTaskComboBox.setMaximumSize(QtCore.QSize(200, 16777215)) self.AssetTaskComboBox.setObjectName("AssetTaskComboBox") self.gridLayout.addWidget(self.AssetTaskComboBox, 1, 1, 1, 1) self.labelAssetType = QtWidgets.QLabel(ExportAssetOptions) self.labelAssetType.setMinimumSize(QtCore.QSize(120, 0)) self.labelAssetType.setMaximumSize(QtCore.QSize(120, 16777215)) self.labelAssetType.setObjectName("labelAssetType") self.gridLayout.addWidget(self.labelAssetType, 0, 0, 1, 1) self.assetNameLabel = QtWidgets.QLabel(ExportAssetOptions) self.assetNameLabel.setMinimumSize(QtCore.QSize(120, 0)) self.assetNameLabel.setMaximumSize(QtCore.QSize(120, 16777215)) self.assetNameLabel.setObjectName("assetNameLabel") self.gridLayout.addWidget(self.assetNameLabel, 4, 0, 1, 1) spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self.gridLayout.addItem(spacerItem, 0, 2, 1, 1) self.label_2 = QtWidgets.QLabel(ExportAssetOptions) self.label_2.setMinimumSize(QtCore.QSize(120, 0)) self.label_2.setMaximumSize(QtCore.QSize(120, 16777215)) self.label_2.setObjectName("label_2") self.gridLayout.addWidget(self.label_2, 3, 0, 1, 1) self.assetTaskLabel_2 = QtWidgets.QLabel(ExportAssetOptions) self.assetTaskLabel_2.setMinimumSize(QtCore.QSize(120, 0)) self.assetTaskLabel_2.setMaximumSize(QtCore.QSize(120, 16777215)) self.assetTaskLabel_2.setObjectName("assetTaskLabel_2") self.gridLayout.addWidget(self.assetTaskLabel_2, 2, 0, 1, 1) self.ListStatusComboBox = QtWidgets.QComboBox(ExportAssetOptions) self.ListStatusComboBox.setMinimumSize(QtCore.QSize(100, 0)) self.ListStatusComboBox.setMaximumSize(QtCore.QSize(200, 16777215)) self.ListStatusComboBox.setObjectName("ListStatusComboBox") self.gridLayout.addWidget(self.ListStatusComboBox, 2, 1, 1, 1) self.verticalLayout.addLayout(self.gridLayout) self.retranslateUi(ExportAssetOptions) self.ListAssetsComboBox.currentIndexChanged[int].connect( ExportAssetOptions.setFilter) self.ListAssetsComboBox.currentIndexChanged[int].connect( ExportAssetOptions.emitAssetType) QtCore.QMetaObject.connectSlotsByName(ExportAssetOptions)
def __init__(self, *args, **kwargs): '''Instantiate the login widget.''' super(Login, self).__init__(*args, **kwargs) layout = QtWidgets.QVBoxLayout() layout.addSpacing(100) layout.setContentsMargins(50, 0, 50, 0) layout.setSpacing(15) self.setLayout(layout) label = QtWidgets.QLabel() label.setText('Sign in') label.setObjectName('login-label') layout.addWidget(label, alignment=QtCore.Qt.AlignCenter) self.server = QtWidgets.QLineEdit() self.server.setPlaceholderText('Site name or custom domain URL') layout.addWidget(self.server) self.username = QtWidgets.QLineEdit() self.username.setPlaceholderText('User name') self.username.hide() layout.addWidget(self.username) self.apiKey = QtWidgets.QLineEdit() self.apiKey.setPlaceholderText('API key') self.apiKey.hide() layout.addWidget(self.apiKey) loginButton = QtWidgets.QPushButton(text='SIGN IN') loginButton.setObjectName('primary') loginButton.clicked.connect(self.handleLogin) loginButton.setMinimumHeight(35) layout.addWidget(loginButton) label = QtWidgets.QLabel() label.setObjectName('lead-label') label.setContentsMargins(0, 0, 0, 0) label.setText( 'Your site name is your ftrackapp.com web address ' '(e.g https://sitename.ftrackapp.com OR your custom domain URL).') label.setAlignment(QtCore.Qt.AlignCenter) label.setWordWrap(True) # Min height is required due to issue when word wrap is True and window # being resized which cases text to dissapear. label.setMinimumHeight(50) label.setMinimumWidth(300) layout.addWidget(label, alignment=QtCore.Qt.AlignCenter) self.errorLabel = QtWidgets.QLabel() self.errorLabel.setWordWrap(True) layout.addWidget(self.errorLabel) self.loginError.connect(self.on_set_error) layout.addStretch(1) self.toggle_api_label = label = ClickableLabel() self.toggle_api_label.setObjectName('lead-label') self.toggle_api_label.setText( 'Trouble signing in? ' '<a href="#" style="color: #1CBC90;">Sign in with username and API key</a>' ) self.toggle_api_label.clicked.connect(self._toggle_credentials) layout.addWidget(self.toggle_api_label, alignment=QtCore.Qt.AlignCenter) layout.addSpacing(20)