class MyWidget(QWidget): def __init__(self): super(MyWidget, self).__init__() self.init_gui() def init_gui(self): self.setWindowTitle("Reimplementing Events") self.setGeometry(300, 250, 300, 100) self.myLayout = QVBoxLayout() self.myLabel = QLabel("Press 'Esc' to close this App") self.infoLabel = QLabel() self.myLabel.setAlignment(Qt.AlignCenter) self.infoLabel.setAlignment(Qt.AlignCenter) self.myLayout.addWidget(self.myLabel) self.myLayout.addWidget(self.infoLabel) self.setLayout(self.myLayout) self.show() def keyPressEvent(self, event: PySide6.QtGui.QKeyEvent) -> None: if event.key() == Qt.Key_Escape: self.close() def mouseDoubleClickEvent(self, event: PySide6.QtGui.QMouseEvent) -> None: self.close() def resizeEvent(self, event: PySide6.QtGui.QResizeEvent) -> None: self.infoLabel.setText("Window Resized to QSize(%d, %d)" % (event.size().width(), event.size().height()))
def __init__(self, parent=None): super().__init__(parent=parent) layout = QtWidgets.QVBoxLayout(self) label1 = QLabel('입력', self) label1.setAlignment(Qt.AlignVCenter) label1.move(200, 30) label2 = QLabel('결과', self) label2.setAlignment(Qt.AlignVCenter) label2.move(710, 30) self.text_box1 = QTextEdit(self) self.text_box1.resize(350, 350) self.text_box1.move(50, 60) self.text_box2 = QTextBrowser(self) self.text_box2.append('') self.text_box2.setGeometry(550, 60, 350, 350) self.ok_base64 = QPushButton("OK", self) self.ok_base64.setGeometry(50, 420, 850, 45) self.ok_base64.clicked.connect(self.base64_conversion) self.back = QPushButton(self) self.back.setStyleSheet( ''' QPushButton{image:url(./img/back_img.png); border:0px;} QPushButton:hover{image:url(./img/back_img_ev_1.png); border:0px;} ''') self.back.setGeometry(0, 0, 50, 50) self.back.clicked.connect(self.change_stack1)
def addChapter(self, row, chapter): if self.downloader.downloaded(chapter): icon = utils.icon("eye") else: icon = utils.icon("download") button = QToolButton() button.setStyleSheet("border: none;") button.setIcon(icon) button.clicked.connect(functools.partial(self.onClicked, chapter)) self.buttons[chapter.id] = button self.setCellWidget(row, 0, button) volume = QLabel(chapter.volume or "(empty)") volume.setAlignment(Qt.AlignCenter) self.setCellWidget(row, 1, volume) id = QLabel(chapter.id) id.setAlignment(Qt.AlignCenter) self.setCellWidget(row, 2, id) title = QLabel( f'<a href="{chapter.url}">{chapter.title or "(empty)"}</a>') title.setOpenExternalLinks(True) self.setCellWidget(row, 3, title)
def __init__(self, data): global instance_id QWidget.__init__(self) self.actionHandler = UIActionHandler() self.actionHandler.setupActionHandler(self) offset_layout = QHBoxLayout() offset_layout.addWidget(QLabel("Offset: ")) self.offset = QLabel(hex(0)) offset_layout.addWidget(self.offset) offset_layout.setAlignment(QtCore.Qt.AlignCenter) datatype_layout = QHBoxLayout() datatype_layout.addWidget(QLabel("Data Type: ")) self.datatype = QLabel("") datatype_layout.addWidget(self.datatype) datatype_layout.setAlignment(QtCore.Qt.AlignCenter) layout = QVBoxLayout() title = QLabel("Hello Pane", self) title.setAlignment(QtCore.Qt.AlignCenter) instance = QLabel("Instance: " + str(instance_id), self) instance.setAlignment(QtCore.Qt.AlignCenter) layout.addStretch() layout.addWidget(title) layout.addWidget(instance) layout.addLayout(datatype_layout) layout.addLayout(offset_layout) layout.addStretch() self.setLayout(layout) instance_id += 1 self.data = data # Populate initial state self.updateState() # Set up view and address change notifications self.notifications = HelloNotifications(self)
def __init__(self, name): global instance_id GlobalAreaWidget.__init__(self, name) self.actionHandler = UIActionHandler() self.actionHandler.setupActionHandler(self) offset_layout = QHBoxLayout() offset_layout.addWidget(QLabel("Offset: ")) self.offset = QLabel(hex(0)) offset_layout.addWidget(self.offset) offset_layout.setAlignment(QtCore.Qt.AlignCenter) datatype_layout = QHBoxLayout() datatype_layout.addWidget(QLabel("Data Type: ")) self.datatype = QLabel("") datatype_layout.addWidget(self.datatype) datatype_layout.setAlignment(QtCore.Qt.AlignCenter) layout = QVBoxLayout() title = QLabel(name, self) title.setAlignment(QtCore.Qt.AlignCenter) instance = QLabel("Instance: " + str(instance_id), self) instance.setAlignment(QtCore.Qt.AlignCenter) layout.addStretch() layout.addWidget(title) layout.addWidget(instance) layout.addLayout(datatype_layout) layout.addLayout(offset_layout) layout.addStretch() self.setLayout(layout) instance_id += 1 self.data = None
class Window(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.clicksCount = 0 self.setupUi() def setupUi(self): self.setWindowTitle("Freezing GUI") self.resize(300, 150) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) # Create and connect widgets self.clicksLabel = QLabel("Counting: 0 clicks", self) self.clicksLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.stepLabel = QLabel("Long-Running Step: 0") self.stepLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.countBtn = QPushButton("Click me!", self) self.countBtn.clicked.connect(self.countClicks) self.longRunningBtn = QPushButton("Long-Running Task!", self) self.longRunningBtn.clicked.connect(self.runLongTask) # Set the layout layout = QVBoxLayout() layout.addWidget(self.clicksLabel) layout.addWidget(self.countBtn) layout.addStretch() layout.addWidget(self.stepLabel) layout.addWidget(self.longRunningBtn) self.centralWidget.setLayout(layout) def countClicks(self): self.clicksCount += 1 self.clicksLabel.setText(f"Counting: {self.clicksCount} clicks") def reportProgress(self, n): self.stepLabel.setText(f"Long-Running Step: {n}") def runLongTask(self): # 创建 QThread self.thread = QThread() # 创建 worker 对象 self.worker = Worker() # 将 work 移到 thread self.worker.moveToThread(self.thread) # 连接信号和槽 self.thread.started.connect(self.worker.run) self.worker.finished.connect(self.thread.quit) self.worker.finished.connect(self.worker.deleteLater) self.thread.finished.connect(self.thread.deleteLater) self.worker.progress.connect(self.reportProgress) # 启动线程 self.thread.start() # 结束 self.longRunningBtn.setEnabled(False) self.thread.finished.connect( lambda: self.longRunningBtn.setEnabled(True)) self.thread.finished.connect( lambda: self.stepLabel.setText("Long-Running Step: 0"))
class Windows_Notification_UI(QWidget): def __init__(self, parent, persepolis_setting): super().__init__(parent) self.persepolis_setting = persepolis_setting # set ui direction ui_direction = self.persepolis_setting.value('ui_direction') if ui_direction == 'rtl': self.setLayoutDirection(Qt.RightToLeft) elif ui_direction in 'ltr': self.setLayoutDirection(Qt.LeftToRight) # set size self.resize(QSize(400, 80)) self.setFixedWidth(400) # show this widget as ToolTip widget self.setWindowFlags(Qt.ToolTip) # find bottom right position bottom_right_screen = QDesktopWidget().availableGeometry().bottomRight( ) bottom_right_notification = QRect(QPoint(0, 0), QSize(410, 120)) bottom_right_notification.moveBottomRight(bottom_right_screen) self.move(bottom_right_notification.topLeft()) # get persepolis icon path icons = ':/' + \ str(self.persepolis_setting.value('settings/icons')) + '/' notification_horizontalLayout = QHBoxLayout(self) # persepolis icon svgWidget = QtSvg.QSvgWidget(':/persepolis.svg') svgWidget.setFixedSize(QSize(64, 64)) notification_horizontalLayout.addWidget(svgWidget) notification_verticalLayout = QVBoxLayout() # 2 labels for notification messages self.label1 = QLabel(self) self.label1.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.label1.setStyleSheet("font-weight: bold") self.label1.setWordWrap(True) self.label2 = QLabel(self) self.label2.setWordWrap(True) self.label2.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) notification_verticalLayout.addWidget(self.label1) notification_verticalLayout.addWidget(self.label2) notification_horizontalLayout.addLayout(notification_verticalLayout)
def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") label = QLabel("Hello") font = label.font() font.setPointSize(30) label.setFont(font) label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.setCentralWidget(label)
def __init__(self): super().__init__() self.setWindowTitle("My App") label = QLabel("Hello!") label.setAlignment(Qt.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar)
def test_text(pixmap_differ: PixmapDiffer): actual: QPainter expected: QPainter with pixmap_differ.create_painters(300, 240, 'scaled_label_text') as (actual, expected): ex_widget = QWidget() ex_layout = QVBoxLayout(ex_widget) ex_label1 = QLabel('Lorem ipsum') ex_label2 = QLabel('Lorem ipsum') ex_font = ex_label1.font() if ex_font.family() == 'Sans Serif': # Fonts are different on GitHub actions. big_font_size = 32 small_font_size = 27 else: big_font_size = 35 small_font_size = 28 ex_font.setPointSize(big_font_size) ex_label1.setFont(ex_font) ex_font.setPointSize(small_font_size) ex_label2.setFont(ex_font) ex_size_policy = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) ex_label1.setSizePolicy(ex_size_policy) ex_label1.setAlignment(Qt.AlignBottom) ex_label2.setAlignment(Qt.AlignTop) ex_label2.setSizePolicy(ex_size_policy) ex_layout.addWidget(ex_label1) ex_layout.addWidget(ex_label2) ex_layout.setStretch(0, 4) ex_layout.setStretch(1, 1) ex_widget.resize(300, 240) expected.drawPixmap(0, 0, ex_widget.grab()) widget = QWidget() layout = QVBoxLayout(widget) label1 = ScaledLabel('Lorem ipsum') label2 = ScaledLabel('Lorem ipsum') size_policy = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) label1.setSizePolicy(size_policy) label2.setSizePolicy(size_policy) label1.setScaledContents(True) label2.setScaledContents(True) label1.setAlignment(Qt.AlignBottom) label2.setAlignment(Qt.AlignTop) layout.addWidget(label1) layout.addWidget(label2) layout.setStretch(0, 4) layout.setStretch(1, 1) widget.resize(300, 240) actual.drawPixmap(0, 0, widget.grab())
class HomeButton(QToolButton): def __init__(self, parent=None): QToolButton.__init__(self) self.setParent(parent)\ # Set the layout of the button layout = QGridLayout() # Button formatting self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setAutoRaise(True) # Icon part of the button self.icon = QLabel() self.icon.setAlignment(Qt.AlignCenter) self.icon.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.iconPixmap = QPixmap() # Text part of the button # Initialise label self.text = QLabel() self.text.setAlignment(Qt.AlignBottom) # TODO: Change colour with universal theme self.text.setStyleSheet("color: white") # Add font styling font = QFont() font.setPixelSize(15) self.text.setFont(font) # Add components to the layer layout.addWidget(self.icon, 0, 0, 3, 3) layout.addWidget(self.text, 2, 0, 1, 3) self.setLayout(layout) def setIcon(self, path): # Set the icon part of the button # path: (str) path to the new icon to use self.icon.setPixmap(QPixmap(path)) self.icon.repaint() def setText(self, text): # Set the text part of the button # text: (str) what the new text part should say self.text.setText(text) def setColour(self, r, g, b): # Set the colour to rgb # r: (int) red value # g: (int) green value # b: (int) blue value self.setStyleSheet( "QToolButton {{ background-color: rgba({}, {}, {}, 0.8)}}\n\nQToolButton:pressed {{ background-color: rgba({}, {}, {}, 1)}}" .format(r, g, b, r, g, b))
def __init__(self, parent, events): super().__init__(parent) self.setWindowTitle("Create Epochs") grid = QGridLayout(self) label = QLabel("Events:") label.setAlignment(Qt.AlignTop) grid.addWidget(label, 0, 0, 1, 1) self.events = QListWidget() self.events.insertItems(0, unique(events[:, 2]).astype(str)) self.events.setSelectionMode(QListWidget.ExtendedSelection) grid.addWidget(self.events, 0, 1, 1, 2) grid.addWidget(QLabel("Interval around events:"), 1, 0, 1, 1) self.tmin = QDoubleSpinBox() self.tmin.setMinimum(-10000) self.tmin.setValue(-0.2) self.tmin.setSingleStep(0.1) self.tmin.setAlignment(Qt.AlignRight) self.tmax = QDoubleSpinBox() self.tmax.setMinimum(-10000) self.tmax.setValue(0.5) self.tmax.setSingleStep(0.1) self.tmax.setAlignment(Qt.AlignRight) grid.addWidget(self.tmin, 1, 1, 1, 1) grid.addWidget(self.tmax, 1, 2, 1, 1) self.baseline = QCheckBox("Baseline Correction:") self.baseline.setChecked(True) self.baseline.stateChanged.connect(self.toggle_baseline) grid.addWidget(self.baseline, 2, 0, 1, 1) self.a = QDoubleSpinBox() self.a.setMinimum(-10000) self.a.setValue(-0.2) self.a.setSingleStep(0.1) self.a.setAlignment(Qt.AlignRight) self.b = QDoubleSpinBox() self.b.setMinimum(-10000) self.b.setValue(0) self.b.setSingleStep(0.1) self.b.setAlignment(Qt.AlignRight) grid.addWidget(self.a, 2, 1, 1, 1) grid.addWidget(self.b, 2, 2, 1, 1) self.buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.buttonbox.accepted.connect(self.accept) self.buttonbox.rejected.connect(self.reject) grid.addWidget(self.buttonbox, 3, 0, 1, -1) self.events.itemSelectionChanged.connect(self.toggle_ok) self.toggle_ok() grid.setSizeConstraint(QGridLayout.SetFixedSize)
def __create_cell(self) -> QWidget: cell_label = QLabel() cell_label.setAlignment(Qt.AlignCenter) cell_label.setStyleSheet("QLabel {font-size: " + str(self._font_size) + "px;}") cell_content = QHBoxLayout() cell_content.addWidget(cell_label) cell = QWidget() cell.setLayout(cell_content) cell.setStyleSheet( f"background-color:{self._default_bg_color}; color:{self._default_color};" ) cell.setFixedSize(self.board_size, self.board_size) return cell
class _Splash(QSplashScreen): def __init__(self, app, splash_text): super().__init__() x, y = app.screens()[0]\ .availableGeometry().size().toTuple() self.setGeometry(x // 2 - 200, y // 2 - 100, 400, 300) self.setFixedSize(400, 200) self.vl = QVBoxLayout(self) self.lb = QLabel(self) self.lb.setAlignment(Qt.AlignCenter) self.lb.setText(splash_text) self.lb.setStyleSheet("font-size: 30px") self.vl.addWidget(self.lb)
def init_ui(self): label = QLabel('カプチーノを入れています...', self) label.setAlignment(Qt.AlignCenter) pbar = QProgressBar(self) pbar.setRange(0, DOUNLOAD_COUNT) pbar.setTextVisible(False) vbox = QVBoxLayout(self) vbox.addWidget(label) vbox.addWidget(pbar) vbox.setContentsMargins(QMargins(16, 16, 16, 16)) self.setLayout(vbox) self.__progress_bar = pbar
def __init__(self): super(MainWindow, self).__init__() self.setWindowTitle("My App") label = QLabel("Hello!") label.setAlignment(Qt.AlignCenter) self.setCentralWidget(label) toolbar = QToolBar("My main toolbar") self.addToolBar(toolbar) button_action = QAction("Your button", self) button_action.setStatusTip("This is your button") button_action.triggered.connect(self.onMyToolBarButtonClick) toolbar.addAction(button_action)
def __init__(self, parent: QWidget, image: QImage, name: str, image_path: Optional[str] = None, array_path: Optional[str] = None): """ Create an ImageEntry :param QWidget parent: The parent containing the ImageEntry. :param QImage image: The image that will be draw in the thumbnail. :param str name: The name that will be shown below the thumbnail. Also used for image basename. :param image_path: Path to the image file. :type image_path: str, optional :param array_path: Path to the Numpy array file. :type array_path: str, optional """ super(ImageEntry, self).__init__(parent) self.__selected = False self.__mouse_pressed_handlers: List[Callable[[ImageEntry, QMouseEvent], Any]] = [] self.setAutoFillBackground(True) self.__default_background_color = self.palette().color( self.backgroundRole()) self.image_path: Final[Optional[str]] = image_path self.array_path: Final[Optional[str]] = array_path self.basename: Final[str] = name thumbnail = QLabel("Thumbnail", self) thumbnail.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) thumbnail.setAlignment(Qt.AlignCenter) thumbnail.setPixmap( fit_to_frame(QPixmap.fromImage(image), QSize(50, 50))) name_label = QLabel('\n'.join(wrap(name, 15)), self) name_label.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Minimum) name_label.setAlignment(Qt.AlignCenter) layout = QVBoxLayout(self) layout.addWidget(thumbnail, alignment=Qt.AlignHCenter) layout.addWidget(name_label, alignment=Qt.AlignHCenter) self.setLayout(layout)
def updateQueue(self): # "Refresh" the queue visually while self.layout.count(): item = self.layout.takeAt(0) if item.widget() is not None: item.widget().deleteLater() for i in self.window().songQueue.getQueue(): item = self.QueueListItem(i, self) self.layout.addWidget(item) if self.window().songQueue.getQueue(): self.layout.addStretch(1) else: label = QLabel("没有结果/No Result") label.setStyleSheet("color: white") label.setAlignment(Qt.AlignCenter) font = QFont() font.setPointSize(35) label.setFont(font) self.layout.addWidget(label)
def addResults(self, results): # Add the results to the list # results (list): list of python dict representing results details (playlist or song search) self.clearResults() for i in range(len(results)): item = self.ResultsGridItem(results[i], self) self.layout.addWidget(item, i // 6, i % 6) if results: self.layout.setRowStretch(self.layout.rowCount(), 1) self.layout.setColumnStretch(self.layout.columnCount(), 1) else: # If the results are empty, display no result label = QLabel("没有结果/No Result") label.setStyleSheet("color: white") label.setAlignment(Qt.AlignCenter) font = QFont() font.setPointSize(35) label.setFont(font) self.layout.addWidget(label)
def addResults(self, results): # Add the results to the list # results (list): list of python dict representing results details (playlist or song search) self.results = results self.clearResults() if results: for i in self.results: item = self.ResultsListItem(i, self) self.layout.addWidget(item) self.layout.addStretch(1) else: # If the results are empty, display no result label = QLabel("没有结果/No Result") label.setStyleSheet("color: white") label.setAlignment(Qt.AlignCenter) font = QFont() font.setPointSize(35) label.setFont(font) self.layout.addWidget(label)
class Window(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.clicksCount = 0 self.setupUi() def setupUi(self): self.setWindowTitle("Freezing GUI") self.resize(300, 150) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) # Create and connect widgets self.clicksLabel = QLabel("Counting: 0 clicks", self) self.clicksLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.stepLabel = QLabel("Long-Running Step: 0") self.stepLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.countBtn = QPushButton("Click me!", self) self.countBtn.clicked.connect(self.countClicks) self.longRunningBtn = QPushButton("Long-Running Task!", self) self.longRunningBtn.clicked.connect(self.runLongTask) # Set the layout layout = QVBoxLayout() layout.addWidget(self.clicksLabel) layout.addWidget(self.countBtn) layout.addStretch() layout.addWidget(self.stepLabel) layout.addWidget(self.longRunningBtn) self.centralWidget.setLayout(layout) def countClicks(self): self.clicksCount += 1 self.clicksLabel.setText(f"Counting: {self.clicksCount} clicks") def reportProgress(self, n): self.stepLabel.setText(f"Long-Running Step: {n}") def runLongTask(self): """Long-running task in 5 steps.""" for i in range(5): sleep(1) self.reportProgress(i + 1)
class MyWidget(QWidget): def __init__(self): QWidget.__init__(self) self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"] self.button = QPushButton("Click me!") self.text = QLabel("Hello World") self.text.setAlignment(Qt.AlignCenter) self.layout = QVBoxLayout() self.layout.addWidget(self.text) self.layout.addWidget(self.button) self.setLayout(self.layout) # Connecting the signal self.button.clicked.connect(self.magic) @Slot() def magic(self): self.text.setText(random.choice(self.hello))
def __init__(self, parent=None): QWidget.__init__(self) self.setParent(parent) # Set layout and spacings layout = QGridLayout() # The heading of the widget label = QLabel("排队的歌曲/Queue List") label.setAlignment(Qt.AlignCenter) label.setFixedHeight(40) # TODO: Change with global themes label.setStyleSheet("color: white;") # Font for the label font = QFont() font.setPixelSize(25) font.setBold(True) label.setFont(font) layout.addWidget(label, 0, 0) self.queueList = self.QueueList(self) layout.addWidget(self.queueList, 1, 0) self.setLayout(layout)
class CLusterPreviewWindow(QWidget): """ Extends QWidget. Floating window next to ClusterEditor showing the current cluster state. """ def __init__(self, parent: Optional[QWidget] = None, size: QSize = QSize(600, 600), image: Optional[QImage] = None): super(CLusterPreviewWindow, self).__init__(parent) self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint) self.resize(size) self.imageLabel = QLabel("Cluster Preview", self) self.imageLabel.setAlignment(Qt.AlignCenter) layout = QGridLayout(self) layout.addWidget(self.imageLabel) if image is not None: self.__update_cluster_preview(QPixmap.fromImage(image)) def __update_cluster_preview(self, image: QPixmap) -> None: self.imageLabel.setPixmap(fit_to_frame(image, QSize(self.width(), self.height()))) def update_cluster_preview(self, image: Union[np.ndarray, str]) -> None: """ Load an image from a string or an array and update the cluster preview. :param image: Can be both a numpy array and a string. """ if isinstance(image, np.ndarray): self.__update_cluster_preview(array2d_to_pixmap(image, normalize=True, colormap=cv.COLORMAP_JET)) return if isinstance(image, str): self.__update_cluster_preview(QPixmap.fromImage(QImage(image))) return raise ValueError("Invalid image type: {}".format(type(image)))
class SyncWidget(QWidget): Sg_view_changed = Signal() def __init__(self, model: SyncModel, parent=None): super(SyncWidget, self).__init__(parent) self._model = model self.watch_label = QLabel(self) self.watch_label.setAlignment(Qt.AlignCenter) self.watch_label.setText("SYNC") self.watch_label.setAccessibleName("Title") self.running_label = QLabel(self) self.running_label.setAlignment(Qt.AlignCenter) self.running_label.setText("Disattivata") self.running_label.setAccessibleName("Subtitle") self.sync_button = QPushButton(self) self.sync_button.setIcon(QIcon(resource_path('icons/reload.png'))) self.sync_button.setIconSize(QSize(50, 50)) self.sync_button.setCheckable(True) self.sync_button.setAccessibleName('HighlightButton') self.menu_label = QLabel(self) self.menu_label.setAlignment(Qt.AlignCenter) self.menu_label.setText("• • •") # create layout self.layout = QVBoxLayout() self.layout.setAlignment(Qt.AlignCenter) self.layout.addWidget(self.watch_label) self.layout.addWidget(self.running_label) self.layout.addWidget(self.sync_button) self.layout.addWidget(self.menu_label) self.setLayout(self.layout) self.sync_button.clicked.connect(self.Sl_button_clicked) self.Sl_model_changed() @Slot() def Sl_button_clicked(self): self.Sg_view_changed.emit() @Slot() def Sl_model_changed(self): self.sync_button.setChecked(self._model.get_state()) if self._model.get_state(): self.running_label.setText("Attivata") else: self.running_label.setText("Disattivata")
class ModernWindow(QWidget): """ Modern window. Args: w (QWidget): Main widget. parent (QWidget, optional): Parent widget. """ def __init__(self, w, parent=None): QWidget.__init__(self, parent) self._w = w self.setupUi() contentLayout = QHBoxLayout() contentLayout.setContentsMargins(0, 0, 0, 0) contentLayout.addWidget(w) self.windowContent.setLayout(contentLayout) self.setWindowTitle(w.windowTitle()) self.setGeometry(w.geometry()) # Adding attribute to clean up the parent window when the child is closed self._w.setAttribute(Qt.WA_DeleteOnClose, True) self._w.destroyed.connect(self.__child_was_closed) def setupUi(self): # create title bar, content self.vboxWindow = QVBoxLayout(self) self.vboxWindow.setContentsMargins(0, 0, 0, 0) self.windowFrame = QWidget(self) self.windowFrame.setObjectName('windowFrame') self.vboxFrame = QVBoxLayout(self.windowFrame) self.vboxFrame.setContentsMargins(0, 0, 0, 0) self.titleBar = WindowDragger(self, self.windowFrame) self.titleBar.setObjectName('titleBar') self.titleBar.setSizePolicy( QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed)) self.hboxTitle = QHBoxLayout(self.titleBar) self.hboxTitle.setContentsMargins(0, 0, 0, 0) self.hboxTitle.setSpacing(0) self.lblTitle = QLabel('Title') self.lblTitle.setObjectName('lblTitle') self.lblTitle.setAlignment(Qt.AlignCenter) spButtons = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) self.btnMinimize = QToolButton(self.titleBar) self.btnMinimize.setObjectName('btnMinimize') self.btnMinimize.setSizePolicy(spButtons) self.btnRestore = QToolButton(self.titleBar) self.btnRestore.setObjectName('btnRestore') self.btnRestore.setSizePolicy(spButtons) self.btnMaximize = QToolButton(self.titleBar) self.btnMaximize.setObjectName('btnMaximize') self.btnMaximize.setSizePolicy(spButtons) self.btnClose = QToolButton(self.titleBar) self.btnClose.setObjectName('btnClose') self.btnClose.setSizePolicy(spButtons) self.vboxFrame.addWidget(self.titleBar) self.windowContent = QWidget(self.windowFrame) self.vboxFrame.addWidget(self.windowContent) self.vboxWindow.addWidget(self.windowFrame) if PLATFORM == "Darwin": self.hboxTitle.addWidget(self.btnClose) self.hboxTitle.addWidget(self.btnMinimize) self.hboxTitle.addWidget(self.btnRestore) self.hboxTitle.addWidget(self.btnMaximize) self.hboxTitle.addWidget(self.lblTitle) else: self.hboxTitle.addWidget(self.lblTitle) self.hboxTitle.addWidget(self.btnMinimize) self.hboxTitle.addWidget(self.btnRestore) self.hboxTitle.addWidget(self.btnMaximize) self.hboxTitle.addWidget(self.btnClose) # set window flags self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowCloseButtonHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint) if QT_VERSION >= (5, ): self.setAttribute(Qt.WA_TranslucentBackground) # set stylesheet with open(_FL_STYLESHEET) as stylesheet: self.setStyleSheet(stylesheet.read()) # automatically connect slots QMetaObject.connectSlotsByName(self) def __child_was_closed(self): self._w = None # The child was deleted, remove the reference to it and close the parent window self.close() def closeEvent(self, event): if not self._w: event.accept() else: self._w.close() event.setAccepted(self._w.isHidden()) def setWindowTitle(self, title): """ Set window title. Args: title (str): Title. """ super(ModernWindow, self).setWindowTitle(title) self.lblTitle.setText(title) def _setWindowButtonState(self, hint, state): btns = { Qt.WindowCloseButtonHint: self.btnClose, Qt.WindowMinimizeButtonHint: self.btnMinimize, Qt.WindowMaximizeButtonHint: self.btnMaximize } button = btns.get(hint) maximized = bool(self.windowState() & Qt.WindowMaximized) if button == self.btnMaximize: # special rules for max/restore self.btnRestore.setEnabled(state) self.btnMaximize.setEnabled(state) if maximized: self.btnRestore.setVisible(state) self.btnMaximize.setVisible(False) else: self.btnMaximize.setVisible(state) self.btnRestore.setVisible(False) else: button.setEnabled(state) allButtons = [ self.btnClose, self.btnMinimize, self.btnMaximize, self.btnRestore ] if True in [b.isEnabled() for b in allButtons]: for b in allButtons: b.setVisible(True) if maximized: self.btnMaximize.setVisible(False) else: self.btnRestore.setVisible(False) self.lblTitle.setContentsMargins(0, 0, 0, 0) else: for b in allButtons: b.setVisible(False) self.lblTitle.setContentsMargins(0, 2, 0, 0) def setWindowFlag(self, Qt_WindowType, on=True): buttonHints = [ Qt.WindowCloseButtonHint, Qt.WindowMinimizeButtonHint, Qt.WindowMaximizeButtonHint ] if Qt_WindowType in buttonHints: self._setWindowButtonState(Qt_WindowType, on) else: QWidget.setWindowFlag(self, Qt_WindowType, on) def setWindowFlags(self, Qt_WindowFlags): buttonHints = [ Qt.WindowCloseButtonHint, Qt.WindowMinimizeButtonHint, Qt.WindowMaximizeButtonHint ] for hint in buttonHints: self._setWindowButtonState(hint, bool(Qt_WindowFlags & hint)) QWidget.setWindowFlags(self, Qt_WindowFlags) @Slot() def on_btnMinimize_clicked(self): self.setWindowState(Qt.WindowMinimized) @Slot() def on_btnRestore_clicked(self): if self.btnMaximize.isEnabled() or self.btnRestore.isEnabled(): self.btnRestore.setVisible(False) self.btnRestore.setEnabled(False) self.btnMaximize.setVisible(True) self.btnMaximize.setEnabled(True) self.setWindowState(Qt.WindowNoState) @Slot() def on_btnMaximize_clicked(self): if self.btnMaximize.isEnabled() or self.btnRestore.isEnabled(): self.btnRestore.setVisible(True) self.btnRestore.setEnabled(True) self.btnMaximize.setVisible(False) self.btnMaximize.setEnabled(False) self.setWindowState(Qt.WindowMaximized) @Slot() def on_btnClose_clicked(self): self.close() @Slot() def on_titleBar_doubleClicked(self): if not bool(self.windowState() & Qt.WindowMaximized): self.on_btnMaximize_clicked() else: self.on_btnRestore_clicked()
class Ui_ProfilesDialog_UI(object): def setupUi(self, ProfilesDialog_UI): if not ProfilesDialog_UI.objectName(): ProfilesDialog_UI.setObjectName(u"ProfilesDialog_UI") ProfilesDialog_UI.resize(594, 639) self.gridLayout_2 = QGridLayout(ProfilesDialog_UI) self.gridLayout_2.setObjectName(u"gridLayout_2") self.button_create = QToolButton(ProfilesDialog_UI) self.button_create.setObjectName(u"button_create") icon = QIcon() iconThemeName = u"document-new" if QIcon.hasThemeIcon(iconThemeName): icon = QIcon.fromTheme(iconThemeName) else: icon.addFile(u".", QSize(), QIcon.Normal, QIcon.Off) self.button_create.setIcon(icon) self.gridLayout_2.addWidget(self.button_create, 0, 4, 1, 1) self.label = QLabel(ProfilesDialog_UI) self.label.setObjectName(u"label") self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) self.button_delete = QToolButton(ProfilesDialog_UI) self.button_delete.setObjectName(u"button_delete") self.button_delete.setEnabled(False) icon1 = QIcon() iconThemeName = u"delete" if QIcon.hasThemeIcon(iconThemeName): icon1 = QIcon.fromTheme(iconThemeName) else: icon1.addFile(u".", QSize(), QIcon.Normal, QIcon.Off) self.button_delete.setIcon(icon1) self.gridLayout_2.addWidget(self.button_delete, 0, 6, 1, 1) self.properties = QGroupBox(ProfilesDialog_UI) self.properties.setObjectName(u"properties") self.gridLayout = QGridLayout(self.properties) self.gridLayout.setObjectName(u"gridLayout") self.aspect_den = QSpinBox(self.properties) self.aspect_den.setObjectName(u"aspect_den") self.aspect_den.setMinimum(1) self.aspect_den.setMaximum(10000) self.gridLayout.addWidget(self.aspect_den, 4, 3, 1, 1) self.size_w = QSpinBox(self.properties) self.size_w.setObjectName(u"size_w") self.size_w.setMinimum(1) self.size_w.setMaximum(10000) self.gridLayout.addWidget(self.size_w, 1, 1, 1, 1) self.size_h = QSpinBox(self.properties) self.size_h.setObjectName(u"size_h") self.size_h.setMinimum(1) self.size_h.setMaximum(10000) self.gridLayout.addWidget(self.size_h, 1, 3, 1, 1) self.fields = QLabel(self.properties) self.fields.setObjectName(u"fields") self.fields.setText(u"interl: 2*fps") self.gridLayout.addWidget(self.fields, 3, 3, 1, 1) self.label_dar = QLabel(self.properties) self.label_dar.setObjectName(u"label_dar") self.label_dar.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_dar, 5, 0, 1, 1) self.label_3 = QLabel(self.properties) self.label_3.setObjectName(u"label_3") self.label_3.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_3, 2, 0, 1, 1) self.description = QLineEdit(self.properties) self.description.setObjectName(u"description") self.gridLayout.addWidget(self.description, 0, 1, 1, 3) self.colorspace = KComboBox(self.properties) self.colorspace.setObjectName(u"colorspace") self.gridLayout.addWidget(self.colorspace, 7, 1, 1, 3) self.label_8 = QLabel(self.properties) self.label_8.setObjectName(u"label_8") sizePolicy = QSizePolicy(QSizePolicy.Maximum, QSizePolicy.Preferred) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.label_8.sizePolicy().hasHeightForWidth()) self.label_8.setSizePolicy(sizePolicy) self.gridLayout.addWidget(self.label_8, 5, 2, 1, 1) self.field_order = QComboBox(self.properties) self.field_order.addItem("") self.field_order.addItem("") self.field_order.setObjectName(u"field_order") self.gridLayout.addWidget(self.field_order, 9, 1, 1, 3) self.display_num = QSpinBox(self.properties) self.display_num.setObjectName(u"display_num") self.display_num.setMinimum(1) self.display_num.setMaximum(10000) self.gridLayout.addWidget(self.display_num, 5, 1, 1, 1) self.label_scanning = QLabel(self.properties) self.label_scanning.setObjectName(u"label_scanning") self.label_scanning.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_scanning, 8, 0, 1, 1) self.label_4 = QLabel(self.properties) self.label_4.setObjectName(u"label_4") sizePolicy.setHeightForWidth(self.label_4.sizePolicy().hasHeightForWidth()) self.label_4.setSizePolicy(sizePolicy) self.gridLayout.addWidget(self.label_4, 2, 2, 1, 1) self.aspect_num = QSpinBox(self.properties) self.aspect_num.setObjectName(u"aspect_num") self.aspect_num.setMinimum(1) self.aspect_num.setMaximum(10000) self.gridLayout.addWidget(self.aspect_num, 4, 1, 1, 1) self.label_6 = QLabel(self.properties) self.label_6.setObjectName(u"label_6") sizePolicy.setHeightForWidth(self.label_6.sizePolicy().hasHeightForWidth()) self.label_6.setSizePolicy(sizePolicy) self.gridLayout.addWidget(self.label_6, 1, 2, 1, 1) self.label_2 = QLabel(self.properties) self.label_2.setObjectName(u"label_2") self.label_2.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_2, 0, 0, 1, 1) self.scanning = QComboBox(self.properties) self.scanning.addItem("") self.scanning.addItem("") self.scanning.setObjectName(u"scanning") self.gridLayout.addWidget(self.scanning, 8, 1, 1, 3) self.frame_num = QSpinBox(self.properties) self.frame_num.setObjectName(u"frame_num") self.frame_num.setMinimum(1) self.frame_num.setMaximum(500000) self.gridLayout.addWidget(self.frame_num, 2, 1, 1, 1) self.display_den = QSpinBox(self.properties) self.display_den.setObjectName(u"display_den") self.display_den.setMinimum(1) self.display_den.setMaximum(10000) self.gridLayout.addWidget(self.display_den, 5, 3, 1, 1) self.verticalSpacer = QSpacerItem(105, 17, QSizePolicy.Minimum, QSizePolicy.Expanding) self.gridLayout.addItem(self.verticalSpacer, 11, 0, 1, 2) self.label_9 = QLabel(self.properties) self.label_9.setObjectName(u"label_9") self.label_9.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_9, 4, 0, 1, 1) self.label_12 = QLabel(self.properties) self.label_12.setObjectName(u"label_12") self.label_12.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_12, 7, 0, 1, 1) self.label_5 = QLabel(self.properties) self.label_5.setObjectName(u"label_5") self.label_5.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_5, 1, 0, 1, 1) self.label_field_order = QLabel(self.properties) self.label_field_order.setObjectName(u"label_field_order") self.label_field_order.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_field_order, 9, 0, 1, 1) self.label_7 = QLabel(self.properties) self.label_7.setObjectName(u"label_7") sizePolicy.setHeightForWidth(self.label_7.sizePolicy().hasHeightForWidth()) self.label_7.setSizePolicy(sizePolicy) self.gridLayout.addWidget(self.label_7, 4, 2, 1, 1) self.frame_den = QSpinBox(self.properties) self.frame_den.setObjectName(u"frame_den") self.frame_den.setMinimum(1) self.frame_den.setMaximum(10000) self.gridLayout.addWidget(self.frame_den, 2, 3, 1, 1) self.label_11 = QLabel(self.properties) self.label_11.setObjectName(u"label_11") self.label_11.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter) self.gridLayout.addWidget(self.label_11, 3, 0, 1, 1) self.effect_warning = KMessageWidget(self.properties) self.effect_warning.setObjectName(u"effect_warning") self.effect_warning.setWordWrap(True) self.effect_warning.setCloseButtonVisible(False) self.effect_warning.setMessageType(KMessageWidget.Warning) self.gridLayout.addWidget(self.effect_warning, 10, 1, 1, 3) self.gridLayout_2.addWidget(self.properties, 1, 0, 1, 8) self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_2.addItem(self.horizontalSpacer, 0, 3, 1, 1) self.button_save = QToolButton(ProfilesDialog_UI) self.button_save.setObjectName(u"button_save") self.button_save.setEnabled(False) icon2 = QIcon() iconThemeName = u"document-save" if QIcon.hasThemeIcon(iconThemeName): icon2 = QIcon.fromTheme(iconThemeName) else: icon2.addFile(u".", QSize(), QIcon.Normal, QIcon.Off) self.button_save.setIcon(icon2) self.gridLayout_2.addWidget(self.button_save, 0, 5, 1, 1) self.horizontalSpacer_2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.gridLayout_2.addItem(self.horizontalSpacer_2, 3, 3, 1, 2) self.buttonBox = QDialogButtonBox(ProfilesDialog_UI) self.buttonBox.setObjectName(u"buttonBox") self.buttonBox.setOrientation(Qt.Horizontal) self.buttonBox.setStandardButtons(QDialogButtonBox.Close) self.gridLayout_2.addWidget(self.buttonBox, 3, 5, 1, 3) self.profiles_list = QComboBox(ProfilesDialog_UI) self.profiles_list.setObjectName(u"profiles_list") self.gridLayout_2.addWidget(self.profiles_list, 0, 1, 1, 1) self.button_default = QPushButton(ProfilesDialog_UI) self.button_default.setObjectName(u"button_default") self.gridLayout_2.addWidget(self.button_default, 3, 0, 1, 3) self.info_message = KMessageWidget(ProfilesDialog_UI) self.info_message.setObjectName(u"info_message") self.info_message.setWordWrap(True) self.gridLayout_2.addWidget(self.info_message, 2, 0, 1, 8) self.retranslateUi(ProfilesDialog_UI) self.buttonBox.accepted.connect(ProfilesDialog_UI.accept) self.buttonBox.rejected.connect(ProfilesDialog_UI.reject) QMetaObject.connectSlotsByName(ProfilesDialog_UI) # setupUi def retranslateUi(self, ProfilesDialog_UI): ProfilesDialog_UI.setWindowTitle(QCoreApplication.translate("ProfilesDialog_UI", u"Profiles", None)) #if QT_CONFIG(tooltip) self.button_create.setToolTip(QCoreApplication.translate("ProfilesDialog_UI", u"Create new profile", None)) #endif // QT_CONFIG(tooltip) self.button_create.setText(QCoreApplication.translate("ProfilesDialog_UI", u"C", None)) self.label.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Profile:", None)) #if QT_CONFIG(tooltip) self.button_delete.setToolTip(QCoreApplication.translate("ProfilesDialog_UI", u"Delete profile", None)) #endif // QT_CONFIG(tooltip) self.button_delete.setText(QCoreApplication.translate("ProfilesDialog_UI", u"D", None)) self.properties.setTitle(QCoreApplication.translate("ProfilesDialog_UI", u"Properties", None)) self.label_dar.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Display aspect ratio:", None)) self.label_3.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Frame rate:", None)) self.label_8.setText(QCoreApplication.translate("ProfilesDialog_UI", u"/", None)) self.field_order.setItemText(0, QCoreApplication.translate("ProfilesDialog_UI", u"Top Field First", None)) self.field_order.setItemText(1, QCoreApplication.translate("ProfilesDialog_UI", u"Bottom Field First", None)) self.label_scanning.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Scanning:", None)) self.label_4.setText(QCoreApplication.translate("ProfilesDialog_UI", u"/", None)) self.label_6.setText(QCoreApplication.translate("ProfilesDialog_UI", u"x", None)) self.label_2.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Description:", None)) self.scanning.setItemText(0, QCoreApplication.translate("ProfilesDialog_UI", u"Interlaced", None)) self.scanning.setItemText(1, QCoreApplication.translate("ProfilesDialog_UI", u"Progressive", None)) self.label_9.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Pixel aspect ratio:", None)) self.label_12.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Colorspace:", None)) self.label_5.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Size:", None)) self.label_field_order.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Field order:", None)) self.label_7.setText(QCoreApplication.translate("ProfilesDialog_UI", u"/", None)) self.label_11.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Fields per second:", None)) self.effect_warning.setText(QCoreApplication.translate("ProfilesDialog_UI", u"The \"avfilter.fieldorder\" effect is internally used to set the field order, but the effect was not found.\n" "This feature will not work as expected.", None)) #if QT_CONFIG(tooltip) self.button_save.setToolTip(QCoreApplication.translate("ProfilesDialog_UI", u"Save profile", None)) #endif // QT_CONFIG(tooltip) self.button_save.setText(QCoreApplication.translate("ProfilesDialog_UI", u"S", None)) self.button_default.setText(QCoreApplication.translate("ProfilesDialog_UI", u"Use as default", None))
def createLabel(self, text): label = QLabel(text) label.setAlignment(Qt.AlignCenter) label.setMargin(2) label.setFrameStyle(QFrame.Box | QFrame.Sunken) return label
import sys from PySide6.QtCore import Qt from PySide6.QtWidgets import QApplication, QLabel if __name__ == '__main__': app = QApplication() w = QLabel("This is a placeholder text") w.setAlignment(Qt.AlignCenter) # 设置css样式 w.setStyleSheet(""" background-color:#262626; color: #FFFFFF; font-size: 18px; """) w.show() sys.exit(app.exec_())
class UITransferROIWindow: def setup_ui(self, transfer_roi_window_instance, signal_roi_transferred_to_fixed_container, signal_roi_transferred_to_moving_container): self.patient_dict_container = PatientDictContainer() self.moving_dict_container = MovingDictContainer() self.fixed_image_initial_rois = self.patient_dict_container.get("rois") self.moving_image_initial_rois = self.moving_dict_container.get("rois") self.transfer_roi_window_instance = transfer_roi_window_instance self.signal_roi_transferred_to_fixed_container = \ signal_roi_transferred_to_fixed_container self.signal_roi_transferred_to_moving_container = \ signal_roi_transferred_to_moving_container self.fixed_to_moving_rois = {} self.moving_to_fixed_rois = {} self.add_suffix = True self.progress_window = ProgressWindow( self, QtCore.Qt.WindowTitleHint | QtCore.Qt.WindowCloseButtonHint) self.progress_window.setFixedSize(250, 100) self.progress_window.signal_loaded \ .connect(self.onTransferRoiFinished) self.progress_window.signal_error.connect(self.onTransferRoiError) self.init_layout() def retranslate_ui(self, transfer_roi_window_instance): _translate = QtCore.QCoreApplication.translate transfer_roi_window_instance.setWindowTitle( _translate("TransferRoiWindowInstance", "OnkoDICOM - Transfer Region of Interest")) self.add_suffix_checkbox.setText( _translate("AddSuffixCheckBox", "Add Suffix")) self.patient_A_label.setText( _translate("PatientAROILabel", "First Image Set ROIs")) self.patient_B_label.setText( _translate("PatientBROILabel", "Second Image Set ROIs")) self.transfer_all_rois_to_patient_B_button.setText( _translate("ROITransferToBButton", "All")) self.transfer_all_rois_to_patient_A_button.setText( _translate("ROITransferToAButton", "All")) self.save_button.setText(_translate("SaveButton", "Save")) self.reset_button.setText(_translate("ResetButton", "Reset")) def init_layout(self): """ Initialize the layout for the Transfer ROI Window. """ if platform.system() == 'Darwin': self.stylesheet_path = "res/stylesheet.qss" else: self.stylesheet_path = "res/stylesheet-win-linux.qss" stylesheet = open(resource_path(self.stylesheet_path)).read() window_icon = QIcon() window_icon.addPixmap(QPixmap(resource_path("res/images/icon.ico")), QIcon.Normal, QIcon.Off) self.transfer_roi_window_instance.setObjectName( "TransferRoiWindowInstance") self.transfer_roi_window_instance.setWindowIcon(window_icon) # Creating a grid layout to hold all elements self.transfer_roi_window_grid_layout = QGridLayout() self.transfer_roi_window_grid_layout.setColumnStretch(0, 1) self.transfer_roi_window_grid_layout.setColumnStretch(1, 1) self.transfer_roi_window_grid_layout.setColumnStretch(2, 1) self.init_patient_labels() self.init_transfer_arrow_buttons() self.init_patient_A_initial_roi_list() self.init_patient_B_rois_to_A_layout() self.init_patient_A_rois_to_B_layout() self.init_patient_B_initial_roi_list() self.init_add_suffix_checkbox() self.init_save_and_reset_button_layout() # Create a new central widget to hold the grid layout self.transfer_roi_window_instance_central_widget = QWidget() self.transfer_roi_window_instance_central_widget.setLayout( self.transfer_roi_window_grid_layout) self.retranslate_ui(self.transfer_roi_window_instance) self.transfer_roi_window_instance.setStyleSheet(stylesheet) self.transfer_roi_window_instance.setCentralWidget( self.transfer_roi_window_instance_central_widget) QtCore.QMetaObject.connectSlotsByName( self.transfer_roi_window_instance) def init_transfer_arrow_buttons(self): """ Initialize the layout for arrow buttons """ self.transfer_all_rois_to_patient_B_button = QPushButton() self.transfer_all_rois_to_patient_B_button.setObjectName( "ROITransferToBButton") transfer_all_rois_to_patient_B_icon = QtGui.QIcon() transfer_all_rois_to_patient_B_icon.addPixmap( QtGui.QPixmap( resource_path('res/images/btn-icons/forward_slide_icon.png')), QtGui.QIcon.Normal, QtGui.QIcon.On) self.transfer_all_rois_to_patient_B_button \ .setIcon(transfer_all_rois_to_patient_B_icon) self.transfer_all_rois_to_patient_B_button.clicked.connect( self.transfer_all_rois_to_patient_B_button_clicked) self.transfer_roi_window_grid_layout.addWidget( self.transfer_all_rois_to_patient_B_button, 1, 1) self.transfer_all_rois_to_patient_A_button = QPushButton() self.transfer_all_rois_to_patient_A_button.setObjectName( "ROITransferToAButton") self.transfer_all_rois_to_patient_A_button.setMaximumWidth(100) transfer_all_rois_to_patient_A_icon = QtGui.QIcon() transfer_all_rois_to_patient_A_icon.addPixmap( QtGui.QPixmap( resource_path('res/images/btn-icons/backward_slide_icon.png')), QtGui.QIcon.Normal, QtGui.QIcon.On) self.transfer_all_rois_to_patient_A_button \ .setIcon(transfer_all_rois_to_patient_A_icon) self.transfer_all_rois_to_patient_A_button.clicked.connect( self.transfer_all_rois_to_patient_A_button_clicked) self.transfer_roi_window_grid_layout.addWidget( self.transfer_all_rois_to_patient_A_button, 2, 1) def transfer_all_rois_to_patient_B_button_clicked(self): """ This function is triggered when the right arrow button is clicked. """ self.fixed_to_moving_rois.clear() self.patient_A_rois_to_B_list_widget.clear() for i in range(0, len(self.fixed_image_initial_rois)): self.patient_A_initial_roi_double_clicked( self.patient_A_initial_rois_list_widget.item(i)) def transfer_all_rois_to_patient_A_button_clicked(self): """ This function is triggered when the left arrow button is clicked. """ self.moving_to_fixed_rois.clear() self.patient_B_rois_to_A_list_widget.clear() for i in range(0, len(self.moving_image_initial_rois)): self.patient_B_initial_roi_double_clicked( self.patient_B_initial_rois_list_widget.item(i)) def init_add_suffix_checkbox(self): """ Initialize the layout for add suffix checkbox """ self.add_suffix_checkbox = QCheckBox() self.add_suffix_checkbox.setObjectName("AddSuffixCheckBox") self.add_suffix_checkbox.setChecked(self.add_suffix) self.add_suffix_checkbox.clicked.connect( self.add_suffix_checkbox_clicked) self.transfer_roi_window_grid_layout.addWidget( self.add_suffix_checkbox, 3, 0) def init_patient_labels(self): """ Initialize the layout for two patient labels """ self.patient_A_label = QLabel() self.patient_A_label.setObjectName("PatientAROILabel") self.patient_A_label.setMinimumHeight(50) self.patient_A_label.setAlignment(Qt.AlignCenter) self.patient_A_label.setStyleSheet( "QLabel { background-color : green; color : white; " "font-size: 15pt; font-weight: bold;}") self.patient_B_label = QLabel() self.patient_B_label.setObjectName("PatientBROILabel") self.patient_B_label.setMinimumHeight(50) self.patient_B_label.setAlignment(Qt.AlignCenter) self.patient_B_label.setStyleSheet( "QLabel { background-color : red; color : white; " "font-size: 15pt; font-weight: bold;}") self.transfer_roi_window_grid_layout.addWidget(self.patient_A_label, 0, 0) self.transfer_roi_window_grid_layout.addWidget(self.patient_B_label, 0, 2) def init_save_and_reset_button_layout(self): """ Initialize the layout for save and reset buttons """ self.reset_and_save_buttons_layout = QHBoxLayout() self.reset_button = QPushButton() self.reset_button.setObjectName("ResetButton") self.reset_button.clicked.connect(self.reset_clicked) self.save_button = QPushButton() self.save_button.setObjectName("SaveButton") self.save_button.setDisabled(True) self.save_button.clicked.connect(self.transfer_roi_clicked) self.reset_and_save_buttons_layout.setAlignment(Qt.AlignRight) self.reset_and_save_buttons_layout.addWidget(self.reset_button) self.reset_and_save_buttons_layout.addWidget(self.save_button) # Create a widget to hold Reset and Save buttons self.reset_and_save_button_central_widget = QWidget() self.reset_and_save_button_central_widget.setLayout( self.reset_and_save_buttons_layout) self.transfer_roi_window_grid_layout.addWidget( self.reset_and_save_button_central_widget, 3, 2) def add_suffix_checkbox_clicked(self): """ This function is triggered when the add suffix checkbox is clicked """ self.add_suffix = self.add_suffix_checkbox.isChecked() def init_patient_B_rois_to_A_layout(self): """ Initialize the layout for transfer rois from B to A container """ # Create scrolling area widget to contain the content. self.patient_B_rois_to_A_list_widget = QListWidget(self) self.transfer_roi_window_grid_layout \ .addWidget(self.patient_B_rois_to_A_list_widget, 2, 0) self.patient_B_rois_to_A_list_widget.itemDoubleClicked.connect( self.patient_B_to_A_rois_double_clicked) def init_patient_A_rois_to_B_layout(self): """ Initialize the layout for transfer rois from A to B container """ self.patient_A_rois_to_B_list_widget = QListWidget(self) self.transfer_roi_window_grid_layout \ .addWidget(self.patient_A_rois_to_B_list_widget, 1, 2) self.patient_A_rois_to_B_list_widget.itemDoubleClicked.connect( self.patient_A_to_B_rois_double_clicked) def init_patient_A_initial_roi_list(self): """ Initialize the layout for patient A's roi list """ self.patient_A_initial_rois_list_widget = QListWidget(self) self.patient_A_initial_rois_list_widget.itemDoubleClicked.connect( self.patient_A_initial_roi_double_clicked) for idx in self.fixed_image_initial_rois: roi_label = QListWidgetItem( self.fixed_image_initial_rois[idx]['name']) roi_label.setForeground(Qt.darkGreen) roi_label.setData(Qt.UserRole, self.fixed_image_initial_rois[idx]) self.patient_A_initial_rois_list_widget.addItem(roi_label) self.transfer_roi_window_grid_layout.addWidget( self.patient_A_initial_rois_list_widget, 1, 0) def init_patient_B_initial_roi_list(self): """ Initialize the layout for patient B's roi list """ self.patient_B_initial_rois_list_widget = QListWidget(self) self.patient_B_initial_rois_list_widget.itemDoubleClicked.connect( self.patient_B_initial_roi_double_clicked) for idx in self.moving_image_initial_rois: roi_label = QListWidgetItem( self.moving_image_initial_rois[idx]['name']) roi_label.setForeground(Qt.red) roi_label.setData(Qt.UserRole, self.moving_image_initial_rois[idx]) self.patient_B_initial_rois_list_widget.addItem(roi_label) self.transfer_roi_window_grid_layout.addWidget( self.patient_B_initial_rois_list_widget, 2, 2) def patient_A_to_B_rois_double_clicked(self, item): """ This function is triggered when a roi in "A to B" list is double-clicked. """ roi_to_remove = item.data(Qt.UserRole) to_delete_value = roi_to_remove['name'] self.fixed_to_moving_rois.pop(to_delete_value) self.patient_A_rois_to_B_list_widget.clear() for key, value in self.fixed_to_moving_rois.items(): roi_label = QListWidgetItem(value) roi_label.setForeground(Qt.red) roi_label.setData(Qt.UserRole, {'name': key}) self.patient_A_rois_to_B_list_widget.addItem(roi_label) if self.transfer_list_is_empty(): self.save_button.setDisabled(True) def patient_B_to_A_rois_double_clicked(self, item): """ This function is triggered when a roi in "B to A" list is double-clicked. """ roi_to_remove = item.data(Qt.UserRole) to_delete_value = roi_to_remove['name'] self.moving_to_fixed_rois.pop(to_delete_value) self.patient_B_rois_to_A_list_widget.clear() for key, value in self.moving_to_fixed_rois.items(): roi_label = QListWidgetItem(value) roi_label.setForeground(Qt.red) roi_label.setData(Qt.UserRole, {'name': key}) self.patient_B_rois_to_A_list_widget.addItem(roi_label) if self.transfer_list_is_empty(): self.save_button.setDisabled(True) def patient_A_initial_roi_double_clicked(self, item): """ This function is triggered when a roi in patient A's roi list is double-clicked. """ roi_to_add = item.data(Qt.UserRole) transferred_roi_name = roi_to_add['name'] # If the clicked roi is already transferred, return if transferred_roi_name in self.fixed_to_moving_rois.keys(): QMessageBox.about(self, "Transfer Failed", "Chosen ROI has already been transferred!") return # Create a set to store all current roi names in target patient # including both initial rois name and added roi names so far patient_B_initial_roi_name_list = set() for item in self.fixed_to_moving_rois.values(): patient_B_initial_roi_name_list.add(item) for idx in self.moving_image_initial_rois: patient_B_initial_roi_name_list.add( self.moving_image_initial_rois[idx]['name']) # Check if clicked roi name has duplicate # in patient B's initial roi names list if transferred_roi_name in patient_B_initial_roi_name_list: if self.add_suffix: transferred_roi_name = generate_non_duplicated_name( transferred_roi_name, patient_B_initial_roi_name_list) else: QMessageBox.about( self, "Transfer Failed", "Duplicated ROI name. " "Please consider adding suffix.") return # Add clicked roi to transferred list self.fixed_to_moving_rois[roi_to_add['name']] = transferred_roi_name roi_label = QListWidgetItem(transferred_roi_name) roi_label.setForeground(Qt.red) roi_label.setData(Qt.UserRole, roi_to_add) self.patient_A_rois_to_B_list_widget.addItem(roi_label) self.save_button.setDisabled(False) def patient_B_initial_roi_double_clicked(self, item): """ This function is triggered when a roi in patient B's roi list is double-clicked. """ roi_to_add = item.data(Qt.UserRole) transferred_roi_name = roi_to_add['name'] # If the clicked roi is already transferred, return if transferred_roi_name in self.moving_to_fixed_rois.keys(): QMessageBox.about(self, "Transfer Failed", "Chosen ROI has already been transferred!") return # Create a set to store all current roi names in target patient # including both initial rois name and added roi names so far patient_A_current_roi_name_list = set() for item in self.moving_to_fixed_rois.values(): patient_A_current_roi_name_list.add(item) for idx in self.fixed_image_initial_rois: patient_A_current_roi_name_list.add( self.fixed_image_initial_rois[idx]['name']) # Check if clicked roi name has duplicate in # target patient's roi names list if transferred_roi_name in patient_A_current_roi_name_list: # if add suffix is ticked, iteratively try adding suffix # from _A to _Z, stop when no duplicate found if self.add_suffix: transferred_roi_name = generate_non_duplicated_name( transferred_roi_name, patient_A_current_roi_name_list) else: QMessageBox.about( self, "Transfer Failed", "Duplicated ROI name. " "Please consider adding suffix.") return # Add clicked roi to transferred list self.moving_to_fixed_rois[roi_to_add['name']] = transferred_roi_name roi_label = QListWidgetItem(transferred_roi_name) roi_label.setForeground(Qt.red) roi_label.setData(Qt.UserRole, roi_to_add) self.patient_B_rois_to_A_list_widget.addItem(roi_label) self.save_button.setDisabled(False) def reset_clicked(self): """ This function is triggered when reset button is clicked. """ self.fixed_to_moving_rois.clear() self.moving_to_fixed_rois.clear() self.patient_A_rois_to_B_list_widget.clear() self.patient_B_rois_to_A_list_widget.clear() self.save_button.setDisabled(True) def transfer_list_is_empty(self): """ This function is to check if the transfer list is empty """ return len(self.fixed_to_moving_rois) == 0 \ and len(self.moving_to_fixed_rois) == 0 def save_clicked(self, interrupt_flag, progress_callback): """ This function is triggered when the save button is clicked. It contains all steps in the ROI transferring process. :param interrupt_flag: interrupt flag to stop process :param progress_callback: signal that receives the current progress of the loading. """ progress_callback.emit(("Converting images to sitk", 0)) # check if interrupt flag is set if not check_interrupt_flag(interrupt_flag): return False rtss = self.patient_dict_container.get("dataset_rtss") # get sitk for the fixed image dicom_image = read_dicom_image_to_sitk( self.patient_dict_container.filepaths) if not check_interrupt_flag(interrupt_flag): return False # get array of roi indexes from sitk images rois_images_fixed = transform_point_set_from_dicom_struct( dicom_image, rtss, self.fixed_to_moving_rois.keys(), spacing_override=None, interrupt_flag=interrupt_flag) moving_rtss = self.moving_dict_container.get("dataset_rtss") if not check_interrupt_flag(interrupt_flag): return False # get sitk for the moving image moving_dicom_image = read_dicom_image_to_sitk( self.moving_dict_container.filepaths) if not check_interrupt_flag(interrupt_flag): return False # get array of roi indexes from sitk images progress_callback \ .emit(("Retrieving ROIs from \nboth image sets", 20)) # check if interrupt flag is set if not check_interrupt_flag(interrupt_flag): return False if moving_rtss: rois_images_moving = transform_point_set_from_dicom_struct( moving_dicom_image, moving_rtss, self.moving_to_fixed_rois.keys(), spacing_override=None, interrupt_flag=interrupt_flag) else: rois_images_moving = ([], []) if not check_interrupt_flag(interrupt_flag): return False tfm = self.moving_dict_container.get("tfm") progress_callback.emit( ("Transfering ROIs from moving \nto fixed image set", 40)) # check if interrupt flag is set if not check_interrupt_flag(interrupt_flag): return False # transform roi from moving_dict to fixed_dict self.transfer_rois(self.moving_to_fixed_rois, tfm, dicom_image, rois_images_moving, self.patient_dict_container) progress_callback.emit( ("Transfering ROIs from fixed \nto moving image set", 60)) if not check_interrupt_flag(interrupt_flag): return False # transform roi from moving_dict to fixed_dict self.transfer_rois(self.fixed_to_moving_rois, tfm.GetInverse(), moving_dicom_image, rois_images_fixed, self.moving_dict_container) progress_callback.emit(("Saving ROIs to RTSS", 80)) # check if interrupt flag is set if not check_interrupt_flag(interrupt_flag): return False progress_callback.emit(("Reloading window", 90)) return True def transfer_roi_clicked(self): """ telling progress window to start ROI transfer """ self.progress_window.start(self.save_clicked) def onTransferRoiError(self, exception): """ This function is triggered when there is an error in the ROI transferring process. :param exception: exception thrown """ QMessageBox.about(self.progress_window, "Unable to transfer ROIs", "Please check your image set and ROI data.") self.progress_window.close() def onTransferRoiFinished(self, result): """ This function is triggered when ROI transferring process is finished. """ # emit changed dataset to structure_modified function and # auto_save_roi function if result[0] is True: if len(self.fixed_to_moving_rois) > 0: self.signal_roi_transferred_to_moving_container.emit( (self.moving_dict_container.get("dataset_rtss"), { "transfer": None })) if len(self.moving_to_fixed_rois) > 0: self.signal_roi_transferred_to_fixed_container.emit( (self.patient_dict_container.get("dataset_rtss"), { "transfer": None })) self.progress_window.close() QMessageBox.about(self.transfer_roi_window_instance, "Saved", "ROIs are successfully transferred!") else: QMessageBox.about(self.transfer_roi_window_instance, "Cancelled", "ROIs Transfer is cancelled.") self.closeWindow() def transfer_rois(self, transfer_dict, tfm, reference_image, original_roi_list, patient_dict_container): """ Converting (transferring) ROIs from one image set to another and save the transferred rois to rtss. :param transfer_dict: dictionary of rois to be transfer. key is original roi names, value is the name after transferred. :param original_roi_list: tuple of sitk rois from the base image. :param tfm: the tfm that contains information for transferring rois :param reference_image: the reference (base) image :param patient_dict_container: container of the transfer image set. """ for roi_name, new_roi_name in transfer_dict.items(): for index, name in enumerate(original_roi_list[1]): if name == roi_name: sitk_image = original_roi_list[0][index] new_contour = apply_linear_transform( input_image=sitk_image, transform=tfm, reference_image=reference_image, is_structure=True) contour = sitk.GetArrayViewFromImage(new_contour) contours = np.transpose(contour.nonzero()) self.save_roi_to_patient_dict_container( contours, new_roi_name, patient_dict_container) def save_roi_to_patient_dict_container(self, contours, roi_name, patient_dict_container): """ Save the transferred ROI to the corresponding rtss. :param contours: np array of coordinates of the ROI to be saved. :param roi_name: name of the ROI to be saved :param patient_dict_container: container of the transfer image set. """ pixels_coords_dict = {} slice_ids_dict = get_dict_slice_to_uid(patient_dict_container) total_slices = len(slice_ids_dict) for contour in contours: curr_slice_id = total_slices - contour[0] if curr_slice_id >= total_slices: curr_slice_id = 0 if curr_slice_id not in pixels_coords_dict: pixels_coords_dict[curr_slice_id] = [ tuple([contour[2], contour[1]]) ] else: pixels_coords_dict[curr_slice_id].append( tuple([contour[2], contour[1]])) rois_to_save = {} for key in pixels_coords_dict.keys(): coords = pixels_coords_dict[key] polygon_list = ROI.calculate_concave_hull_of_points(coords) if len(polygon_list) > 0: rois_to_save[key] = { 'ds': patient_dict_container.dataset[key], 'coords': polygon_list } roi_list = ROI.convert_hull_list_to_contours_data( rois_to_save, patient_dict_container) if len(roi_list) > 0: print("Saving ", roi_name) if isinstance(patient_dict_container, MovingDictContainer): new_rtss = ROI.create_roi( patient_dict_container.get("dataset_rtss"), roi_name, roi_list, rtss_owner="MOVING") self.moving_dict_container.set("dataset_rtss", new_rtss) self.moving_dict_container.set("rtss_modified", True) else: new_rtss = ROI.create_roi( patient_dict_container.get("dataset_rtss"), roi_name, roi_list) self.patient_dict_container.set("dataset_rtss", new_rtss) self.patient_dict_container.set("rtss_modified", True) def closeWindow(self): """ function to close transfer roi window """ self.close()