def buildTimeline(self, thumbs: list) -> None: thumbslayout = QHBoxLayout() thumbslayout.setSizeConstraint(QLayout.SetFixedSize) thumbslayout.setSpacing(0) thumbslayout.setContentsMargins(0, 16, 0, 0) for thumb in thumbs: thumblabel = QLabel() thumblabel.setStyleSheet('padding: 0; margin: 0;') thumblabel.setFixedSize(thumb.size()) thumblabel.setPixmap(thumb) thumbslayout.addWidget(thumblabel) thumbnails = QWidget(self) thumbnails.setLayout(thumbslayout) filmlabel = QLabel() filmlabel.setObjectName('filmstrip') filmlabel.setFixedHeight( VideoService.config.thumbnails['TIMELINE'].height() + 2) filmlabel.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) filmlayout = QHBoxLayout() filmlayout.setContentsMargins(0, 0, 0, 16) filmlayout.setSpacing(0) filmlayout.addWidget(filmlabel) filmstrip = QWidget(self) filmstrip.setLayout(filmlayout) self.removeThumbs() self.parent.sliderWidget.addWidget(filmstrip) self.parent.sliderWidget.addWidget(thumbnails) self.thumbnailsOn = True self.initStyle() self.parent.sliderWidget.setLoader(False) if self.parent.newproject: self.parent.renderClipIndex() self.parent.newproject = False
def __init__(self, name, picker): super(PickerWidget, self).__init__() self.picker = picker layout = QHBoxLayout() self.setLayout(layout) checkbox = QCheckBox(name) checkbox.setSizePolicy( QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) checkbox.setMinimumWidth(100) checkbox.stateChanged.connect(self.check) layout.addWidget(checkbox) self.checkbox = checkbox slider = QSlider(Qt.Horizontal) slider.setMinimumWidth(300) slider.setMinimum(0) slider.setMaximum(100) slider.setValue(100) slider.valueChanged.connect(self.slide) layout.addWidget(slider) self.slider = slider label = QLabel('0%') label.setMinimumWidth(40) label.setAlignment(Qt.AlignRight) layout.addWidget(label) self.label = label layout.setSizeConstraint(QLayout.SetFixedSize)
def __init__(self, youtubeTitle, YoutubeLink, imageLink, imageSizeW, imageSizeH, parent=None): super(YoutubeQWidget, self).__init__(parent) labelimg = QLabel(self) pixmap = QPixmap() data = urllib.request.urlopen(imageLink).read() pixmap.loadFromData(data) labelimg.setPixmap(pixmap) # Optional, resize window to image size self.resize(pixmap.width(), pixmap.height()) label = QLabel(str(youtubeTitle)) label.setWordWrap(1) label.setFixedWidth(150) label.setStyleSheet('text-align:left') button = QPushButton('play') button.setFixedWidth(100) # print(grade_temp) layout = QHBoxLayout() layout.setSizeConstraint(100) layout.addWidget(labelimg) layout.addWidget(label) layout.addWidget(button) self.setLayout(layout)
def cmd_ask_file(view, sender, content): accepter = QPushButton("Accepter") ignorer = QPushButton("Ignorer") accepter.clicked.connect( lambda: view.signal_handle_file.emit("YES", content.split()[0])) ignorer.clicked.connect( lambda: view.signal_handle_file.emit("NO", content.split()[0])) message = f"{sender} désire vous envoyer un fichier nommé {content.split()[2]} de {content.split()[1]} bytes. " \ f"Acceptez-vous ?" view.my_file_requests[content.split()[0]] = (content.split()[2], content.split()[1]) # create a new widget to display the message and the buttons at once widgetLayout = QHBoxLayout() widgetLayout.addWidget(QLabel(message)) widgetLayout.addWidget(accepter) widgetLayout.addWidget(ignorer) widgetLayout.addStretch() widgetLayout.setSizeConstraint(QLayout.SetFixedSize) widget = QWidget() widget.setLayout(widgetLayout) item = QListWidgetItem() item.setSizeHint(widget.sizeHint()) return item, widget
class TextViewDialog(QDialog): def __init__(self, parent, text): super().__init__(parent) self.text = text self.setupUi() def setupUi(self): self.resize(640, 480) self.verticalLayout = QVBoxLayout(self) self.textEdit = QPlainTextEdit(self) self.closeButton = QPushButton(self) self.copyButton = QPushButton(self) self.verticalLayout.addWidget(self.textEdit) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSizeConstraint(QLayout.SetDefaultConstraint) spacerItem = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) self.horizontalLayout.addItem(spacerItem) self.horizontalLayout.addWidget(self.copyButton) self.horizontalLayout.addWidget(self.closeButton) self.verticalLayout.addLayout(self.horizontalLayout) self.closeButton.clicked.connect(self.reject) self.closeButton.setText('Close') self.copyButton.setText('Copy to clipboard') self.textEdit.setPlainText(self.text) self.copyButton.clicked.connect(self.copy_text) def copy_text(self): clipboard = QApplication.clipboard() clipboard.setText(self.textEdit.toPlainText())
def __init__(self, parent=None, time=1000, message=''): super(NotificationWindow, self).__init__(parent) layout = QHBoxLayout() self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.FramelessWindowHint) desktop = QtWidgets.QDesktopWidget() self.desktopSize = (desktop.screenGeometry().width(), desktop.screenGeometry().height(), desktop.availableGeometry().width(), desktop.availableGeometry().height()) self.resize(self.desktopSize[0] / 1.5, 30) self.icon_label = QLabel("", self) self.icon_label.resize(30, 30) self.icon_label.move(0, 0) self.icon_label.setStyleSheet("background:rgba(0, 0, 0, 0);") self.icon_label.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) layout.setSizeConstraint(layout.SetNoConstraint) layout.addWidget(self.icon_label) layout.setContentsMargins(0, 0, 0, 0) label = QLabel(message, self) label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # label.move(32, 4) label.setStyleSheet("background:rgba(0, 0, 0, 0);") layout.addSpacing(20) layout.addWidget(label) self.setLayout(layout) self.setupAnim(time)
def rendersearchlist(): # mydic_list1 has all the search history. You can iterate with the keywords # for i in mydic_list1 for i in range(len(mydic_list1)): layout = QHBoxLayout() layout.setSizeConstraint(QLayout.SetMinimumSize) item = QListWidgetItem(mpg.listWidget_2) # SAAD DB DONE COMMENTED BELOW in main label = QLabel(str(i+1)+ ") " + mydic_list1[i] ) label.setStyleSheet("height:fit-content;font-size:12pt;font-family: Segoe UI;font-style: normal;font-weight:100") label.setWordWrap(True); layout.addWidget(label) widget = QWidget() widget.setStyleSheet("height:fit-content;width:100%"); widget.setLayout(layout); item.setSizeHint(layout.sizeHint()) mpg.listWidget_2.addItem(item) mpg.listWidget_2.setItemWidget(item,widget)
def init_ui(self): box_layout = QHBoxLayout() layout = QHBoxLayout() layout.setSizeConstraint(QLayout.SetFixedSize) name_label = QLabel('<b>' + self.user + ':</b>') name_label.setObjectName("nameLabel") text_label = QLabel(self.message) text_label.setObjectName("textLabel") text_label.setWordWrap(True) text_label.setTextInteractionFlags(Qt.TextSelectableByMouse) layout.addWidget(name_label, alignment=Qt.AlignLeft) layout.addWidget(text_label, alignment=Qt.AlignLeft) client = QWidget() client.setObjectName("ownMessage" if self.user == "You" else "message") client.setLayout(layout) if self.user == "You": box_layout.addWidget(client, alignment=Qt.AlignRight) else: box_layout.addWidget(client, alignment=Qt.AlignLeft) box_layout.setSpacing(0) box_layout.setContentsMargins(10, 3, 2, 3) self.setLayout(box_layout)
class GOQT(QWidget): def __init__(self, maingo): super().__init__() self.maingo = maingo self.initUI() def initUI(self): self.move(0, 0) self.setWindowTitle('Go') self.hb = QHBoxLayout() self.hb.setContentsMargins(0, 0, 0, 0) self.oldSizeConstraing = self.hb.sizeConstraint() self.stack = QStackedWidget() self.authorizeWidget = AuthorizeWidget(self.maingo, self) self.changeWidget(self.authorizeWidget) self.hb.addWidget(self.stack) self.setLayout(self.hb) self.show() def changeWidget(self, widget, oldsize=True): if oldsize: self.hb.setSizeConstraint(self.oldSizeConstraing) else: self.hb.setSizeConstraint(QLayout.SetFixedSize) if self.stack.currentWidget() != 0: self.stack.removeWidget(self.stack.currentWidget()) self.stack.addWidget(widget) self.stack.setCurrentWidget(widget)
def __init__(self, color_data_filename, user_defined=None): super(ColorMapPreset, self).__init__() self.color_data_filename = color_data_filename with open(color_data_filename, 'r') as file: color_data = json.load(file) self.values = list(color_data[0]["RGBPoints"][::4]) self.colors = list( zip(color_data[0]["RGBPoints"][1::4], color_data[0]["RGBPoints"][2::4], color_data[0]["RGBPoints"][3::4])) layout = QHBoxLayout() self.bar = QLabel() layout.addWidget(self.bar) self.bar.setPixmap(self.create_pixmap()) self.name = QLabel(color_data[0]["Name"]) font = self.name.font() font.setBold(True) font.setPointSize(9) font.setUnderline(True) self.name.setFont(font) layout.addWidget(self.name) layout.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(layout) self.user_defined = user_defined
def cmd_ask_whisper(view, sender, content): print("in cmd_ask_whisper") accepter = QPushButton("Accepter") ignorer = QPushButton("Ignorer") accepter.clicked.connect( lambda: view.signal_handle_whisper.emit("YES", sender)) ignorer.clicked.connect( lambda: view.signal_handle_whisper.emit("NO", sender)) message = f"{sender} désire lancer une conversation privée. Acceptez-vous ?" # create a new widget to display the message and the buttons at once widgetLayout = QHBoxLayout() widgetLayout.addWidget(QLabel(message)) widgetLayout.addWidget(accepter) widgetLayout.addWidget(ignorer) widgetLayout.addStretch() widgetLayout.setSizeConstraint(QLayout.SetFixedSize) widget = QWidget() widget.setLayout(widgetLayout) item = QListWidgetItem() item.setSizeHint(widget.sizeHint()) return item, widget
def success(self, date: datetime, records: Records): self.active(True) _, days_in_month = monthrange(date.year, date.month) self.table.setRowCount(days_in_month) today = datetime.now().strftime("%Y-%m-%d") today_row = None for row, (d, recs) in enumerate(records.records.items()): if today == d: today_row = row self.table.setItem( row, 0, QTableWidgetItem(datetime.strptime(d, "%Y-%m-%d").strftime("%A %d %B")), ) widget = QWidget() widget_text = QLabel("<br>".join(str(r) for r in recs)) widget_layout = QHBoxLayout() widget_layout.addWidget(widget_text) widget_layout.setSizeConstraint(QLayout.SetFixedSize) widget.setLayout(widget_layout) self.table.setCellWidget(row, 1, widget) self.resize_table() self.table.resizeRowsToContents() self.context.clear_status() if today_row is not None: self.table.selectRow(today_row)
class SubToolTip(QWidget): """ 自定义圆角提示气泡子窗口 """ def __init__(self,text='',parent=None): super().__init__(parent) # 换行标志位 self.isWordWrap = False # 实例化小部件 self.timer = QTimer(self) self.label = QLabel(text, self) self.all_h_layout = QHBoxLayout() self.dropShadowEffect = QGraphicsDropShadowEffect(self) # 初始化小部件 self.initLayout() self.initWidget() self.setText(text) def initWidget(self): """ 初始化小部件 """ self.setMaximumSize(400,60) self.setAttribute(Qt.WA_TranslucentBackground) self.label.setStyleSheet(""" QLabel{font:15px "Microsoft YaHei"; background:transparent} """) # 设置阴影 self.dropShadowEffect.setBlurRadius(40) self.dropShadowEffect.setOffset(0,5) self.setGraphicsEffect(self.dropShadowEffect) def initLayout(self): """ 初始化布局 """ self.all_h_layout.addWidget(self.label, 0, Qt.AlignCenter) self.all_h_layout.setContentsMargins(9, 9, 9, 9) # 根据布局的内小部件大小调整窗体大小 self.all_h_layout.setSizeConstraint(QHBoxLayout.SetFixedSize) self.setLayout(self.all_h_layout) def setText(self,text:str): """ 设置提示文字 """ newText, self.isWordWrap = autoWrap(text, 48) self.label.setText(newText) # 如果有换行发生就调整宽度 if self.isWordWrap: self.setMaximumHeight(60) else: self.setMaximumHeight(38) def paintEvent(self, e): """ 绘制圆角背景 """ pen = QPen(QColor(204, 204, 204)) painter = QPainter(self) # 反锯齿 painter.setRenderHint(QPainter.Antialiasing) # 绘制边框 painter.setPen(pen) # 绘制背景 brush = QBrush(QColor(242, 242, 242)) painter.setBrush(brush) painter.drawRoundedRect(self.rect(), 7, 7)
def infoRow(name): row = QHBoxLayout() row.setSizeConstraint(QtWidgets.QLayout.SetMinimumSize) font = QtGui.QFont() font.setPointSize(9) font.setBold(True) font.setWeight(75) first = QLabel() first.setFont(font) first.setText(name) first.setAlignment(QtCore.Qt.AlignRight | QtCore.Qt.AlignTop | QtCore.Qt.AlignTrailing) font = QtGui.QFont() font.setPointSize(9) second = QLabel(text='') second.setFont(font) second.setObjectName(name) second.setOpenExternalLinks(True) second.setAlignment(QtCore.Qt.AlignLeading | QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) row.addWidget(first) row.addWidget(second) return row
def songInfo(self): lMain = QHBoxLayout() vlSub = QVBoxLayout() hlSub = QHBoxLayout() '''Set song image''' songImg = QLabel("IMG") songImg.setFixedSize(80,80) songImg.setStyleSheet("background-color: lightgreen;") path = "img/main.png" pic = QPixmap(path) like = QPushButton("..") like.setFixedSize(20,20) like.setStyleSheet("background-color: lightgreen") # songImg.setPixmap(pic) title = QLabel("This IS The Song Title") title.setStyleSheet("padding:2px,0px,20px,20px;color:white;font-family:'Serif'") artist = QLabel("Artist Name") artist.setStyleSheet("padding:0px,5px,20px,20px;color:white;font-family:'Serif'") hlSub.addWidget(title) hlSub.addWidget(like) vlSub.addLayout(hlSub) vlSub.addWidget(artist) hlSub.addStretch(0) lMain.addWidget(songImg) lMain.addLayout(vlSub) lMain.addStretch(0) lMain.setSizeConstraint(QHBoxLayout.SetFixedSize) return lMain
def init_table_card_widgets(self): for i in range(5): layout = QHBoxLayout(self.p2_rows_widgets[i]) layout.setSizeConstraint(QLayout.SetFixedSize) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(SPACE_BETWEEN_CARDS_SAME_ROW) cards = [] for j in range(5): card = QLabel(self.p2_rows_widgets[i]) card.setMinimumSize(QSize(110, 160)) card.setMaximumSize(QSize(110, 160)) card.setScaledContents(True) layout.addWidget(card) cards.append(card) self.p2_card_widgets.append(cards) for i in range(5): layout = QHBoxLayout(self.p1_rows_widgets[i]) layout.setSizeConstraint(QLayout.SetFixedSize) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(SPACE_BETWEEN_CARDS_SAME_ROW) cards = [] for j in range(5): card = QLabel(self.p1_rows_widgets[i]) card.setMinimumSize(QSize(110, 160)) card.setMaximumSize(QSize(110, 160)) card.setScaledContents(True) layout.addWidget(card) cards.append(card) self.p1_card_widgets.append(cards)
def __init__(self, parent=None): super(FindAndReplaceDlg, self).__init__(parent) findLabel = QLabel("Find &what:") self.findLineEdit = QLineEdit() #Remove auto capitalization self.findLineEdit.setInputMethodHints(Qt.ImhNoAutoUppercase) findLabel.setBuddy(self.findLineEdit) replaceLabel = QLabel("Replace w&ith:") self.replaceLineEdit = QLineEdit() #Remove auto capitalization self.replaceLineEdit.setInputMethodHints(Qt.ImhNoAutoUppercase) replaceLabel.setBuddy(self.replaceLineEdit) self.caseCheckBox = QCheckBox("&Case sensitive") self.wholeCheckBox = QCheckBox("Wh&ole words") moreFrame = QFrame() moreFrame.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) self.backwardsCheckBox = QCheckBox("Search &Backwards") self.regexCheckBox = QCheckBox("Regular E&xpression") line = QFrame() line.setFrameStyle(QFrame.VLine | QFrame.Sunken) self.findButton = QPushButton("&Find") self.replaceButton = QPushButton("&Replace") self.replaceAllButton = QPushButton("&ReplaceAll") self.findButton.setFocusPolicy(Qt.NoFocus) self.replaceButton.setFocusPolicy(Qt.NoFocus) self.replaceAllButton.setFocusPolicy(Qt.NoFocus) gridLayout = QGridLayout() leftLayout = QVBoxLayout() gridLayout.addWidget(findLabel, 0, 0) gridLayout.addWidget(self.findLineEdit, 0, 1) gridLayout.addWidget(replaceLabel, 1, 0) gridLayout.addWidget(self.replaceLineEdit, 1, 1) gridLayout.addWidget(self.caseCheckBox, 2, 0) gridLayout.addWidget(self.wholeCheckBox, 2, 1) gridLayout.addWidget(self.backwardsCheckBox, 3, 0) gridLayout.addWidget(self.regexCheckBox, 3, 1) leftLayout.addLayout(gridLayout) buttonLayout = QVBoxLayout() buttonLayout.addWidget(self.findButton) buttonLayout.addWidget(self.replaceButton) buttonLayout.addWidget(self.replaceAllButton) buttonLayout.addStretch() mainLayout = QHBoxLayout() mainLayout.addLayout(leftLayout) mainLayout.addWidget(line) mainLayout.addLayout(buttonLayout) self.setLayout(mainLayout) mainLayout.setSizeConstraint(QLayout.SetFixedSize) self.findLineEdit.textEdited.connect(self.updateUi) self.findButton.clicked.connect(self.findClicked) self.replaceButton.clicked.connect(self.replaceClicked) self.replaceAllButton.clicked.connect(self.replaceAllClicked) self.updateUi() self.setWindowTitle("Find and Replace")
class ToolTip(QWidget): """ 气泡的父级窗口 """ def __init__(self, text: str = '', parent=None): super().__init__(parent) # 实例化气泡子窗口 self.subToolTip = SubToolTip(text, parent=self) # 实例化布局和定时器 self.all_h_layout = QHBoxLayout() self.timer = QTimer(self) # 初始化部件和布局 self.initWidget() self.initLayout() def initWidget(self): """ 初始化小部件 """ # 设置自己为无边框窗口 self.setWindowFlags(Qt.FramelessWindowHint | Qt.Window) # 设置背景透明和鼠标穿透 self.setAttribute(Qt.WA_TranslucentBackground) self.setStyleSheet('background:transparent') self.setAutoFillBackground(False) self.timer.setInterval(5000) self.timer.timeout.connect(self.timeoutEvent) # 引用子窗口的setText成员函数 self.setText = self.subToolTip.setText self.isWordWrap = self.subToolTip.isWordWrap def initLayout(self): """ 初始化布局 """ self.all_h_layout.addWidget(self.subToolTip, 0, Qt.AlignCenter) self.all_h_layout.setContentsMargins(40,40,40,40) # 根据布局的内小部件大小调整窗体大小 self.all_h_layout.setSizeConstraint(QHBoxLayout.SetFixedSize) self.setLayout(self.all_h_layout) def timeoutEvent(self): """ 定时器溢出时隐藏提示条 """ self.hide() self.timer.stop() def show(self): """ 显示提示条并打开定时器 """ # 窗口置顶 self.raise_() self.timer.start() super().show() def hide(self): """ 隐藏提示条并停止定时器 """ if not self.timer.isActive(): self.timer.stop() super().hide() def leaveEvent(self, e): # 由于自己会捕获leaveEvent,所以如果自己leaveEvent被触发说明兄弟部件的leaveEvent也被触发了 self.hide()
def __init__(self, parent=None): super().__init__(parent) self._thumb = QLabel() self._thumb.setMaximumWidth(100) self._thumb.setMaximumHeight(100) self._name = QComboBox() self._name.setEditable(True) wl = QHBoxLayout() wl.addWidget(self._thumb) wl.addWidget(self._name) wl.addStretch() wl.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(wl)
def _load_ui(self): main_layout = QVBoxLayout(self) main_layout.addWidget(QLabel(translations.TR_SESSIONS_DIALOG_BODY)) main_hbox = QHBoxLayout() # Session list session_layout = QVBoxLayout() self._session_list = QTreeWidget() self._session_list.setHeaderLabels(["Session", "Last Modified"]) session_layout.addWidget(self._session_list) # Content frame content_frame = QFrame() content_frame.hide() frame_layout = QVBoxLayout(content_frame) content_frame.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) session_layout.addWidget(content_frame) frame_layout.setContentsMargins(0, 0, 0, 0) self._content_list = QTreeWidget() self._content_list.setHeaderHidden(True) frame_layout.addWidget(self._content_list) # Separator line line_frame = QFrame() line_frame.setFrameStyle(QFrame.VLine | QFrame.Sunken) # Buttons btn_layout = QVBoxLayout() btn_create = QPushButton(translations.TR_SESSIONS_BTN_CREATE) btn_activate = QPushButton(translations.TR_SESSIONS_BTN_ACTIVATE) btn_update = QPushButton(translations.TR_SESSIONS_BTN_UPDATE) btn_delete = QPushButton(translations.TR_SESSIONS_BTN_DELETE) btn_details = QPushButton(translations.TR_SESSIONS_BTN_DETAILS) btn_details.setCheckable(True) # Add buttons to layout btn_layout.addWidget(btn_create) btn_layout.addWidget(btn_activate) btn_layout.addWidget(btn_update) btn_layout.addWidget(btn_delete) btn_layout.addStretch() btn_layout.addWidget(btn_details) # Add widgets and layouts to the main layout main_layout.addLayout(main_hbox) main_hbox.addLayout(session_layout) main_hbox.addWidget(line_frame) main_hbox.addLayout(btn_layout) main_hbox.setSizeConstraint(QLayout.SetFixedSize) btn_details.toggled[bool].connect(content_frame.setVisible) # Connections self._session_list.itemSelectionChanged.connect( self.load_session_content) btn_activate.clicked.connect(self.open_session) btn_update.clicked.connect(self.save_session) btn_create.clicked.connect(self.create_session) btn_delete.clicked.connect(self.delete_session)
def __init__(self, parent): # Call superclass constructor super().__init__() # Save parent instance self.parent = parent # Box containing display button leftbox = QHBoxLayout() # Decide button self.button_decide = QPushButton('DECIDE', self) self.button_decide.clicked.connect(self.buttonClicked) self.button_decide.setFixedWidth(225) leftbox.addWidget(self.button_decide) # Box conatining output display and label rightbox = QHBoxLayout() # Result label result_label = QLabel('What should you do?:', self) result_label.setAlignment(Qt.AlignRight | Qt.AlignCenter) rightbox.addWidget(result_label) # Result display result_str = "Select some parameters and hit 'DECIDE'" self.result_display = QLabel(result_str, self) self.result_display.setAlignment(Qt.AlignCenter) self.result_display.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.result_display.setLineWidth(3) self.result_display.setFixedWidth(300) rightbox.addWidget(self.result_display) # Animation timer self.anim_timer = QTimer() self.anim_timer.timeout.connect(self.doOutput) self.frame_count = 0 # Color palettes self.setAutoFillBackground(True) palette = self.palette() palette.setColor(self.backgroundRole(), Qt.white) self.setPalette(palette) # Set up layout hbox = QHBoxLayout() hbox.addLayout(leftbox) hbox.insertSpacing(1, 57) hbox.addLayout(rightbox) hbox.setSizeConstraint(QLayout.SetFixedSize) self.setLayout(hbox)
def renderselllist(): for i in mydic_list: if (i["uploaded_by"] == cu and i["status"] == "For Sale"): # EVERYTHING HERE with i # pass # pass # for i in range(len(mydic_list)): layout = QHBoxLayout() layout.setSizeConstraint(QLayout.SetMinimumSize) print(i["short_description"]) print(i) item = QListWidgetItem(mpg.listWidget_3) # SAAD DB DONE COMMENTED label = QLabel( str(i + 1) + ") Title: " + i['short_description'] + "\n" + "Uploaded By: " + str(i['uploaded_by']) + "\n" + "Rating: " + str(i['rating']) + "/5") # label = QLabel(str(i+1)+ ") Title:" + i['short_description'] + "\n" + " Request By: " + i['requested_by'] +"\n" +" Rating: " + str(i['rating']) + "/5") label.setStyleSheet( "height:fit-content;font-size:12pt;font-family: Segoe UI;font-style: normal;font-weight:100" ) label.setWordWrap(True) # label2 = QLabel("No of comments " + str(len(i['comments'])) + '\nStatus: ' + i['status']) label2 = QLabel("Data Size: " + i['data_size'] + '\nStatus: ' + i['status']) label2.setStyleSheet( "height:fit-content;font-size:12pt;font-family: Segoe UI;text-align:right" ) label2.setAlignment(QtCore.Qt.AlignCenter) label2.setWordWrap(True) layout.addWidget(label) layout.addWidget(label2) widget = QWidget() widget.setStyleSheet("height:fit-content;width:100%") widget.setLayout(layout) item.setSizeHint(layout.sizeHint()) mpg.listWidget_3.addItem(item) mpg.listWidget_3.setItemWidget(item, widget)
def initUI(self): self.setSizePolicy( QSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding)) align = QHBoxLayout(self) align.setSizeConstraint(QLayout.SetMaximumSize) self.text.setWordWrap(True) ## self.text.setSizePolicy( ## QSizePolicy( ## QSizePolicy.ShrinkFlag | QSizePolicy.ExpandFlag, #### QSizePolicy.Preferred, ## QSizePolicy.MinimumExpanding ## ) ## ) align.addWidget(self.text) align.addStretch(0) align.addSpacing(20)
def setupUi(self, Dialog, text): self.Dialog = Dialog self.Dialog.setObjectName("Dialog") Dialog.setWindowTitle("Lade...") Dialog.setStyleSheet( "background-color: {}; color: white".format("rgb(47, 69, 80)") ) Dialog.setWindowFlags(Qt.Dialog | Qt.CustomizeWindowHint | Qt.WindowTitleHint) # Dialog.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) horizontalLayout = QHBoxLayout(Dialog) horizontalLayout.setObjectName("horizontal") horizontalLayout.setSizeConstraint(QHBoxLayout.SetFixedSize) # if icon == True: # pixmap = QtGui.QPixmap(logo_cria_button_path) # # Dialog.setPixmap(pixmap.scaled(110, 110, Qt.KeepAspectRatio)) # image = QLabel(Dialog) # image.setObjectName("image") # image.setPixmap(pixmap.scaled(30, 30, Qt.KeepAspectRatio)) self.label = QLabel(Dialog) self.label.setObjectName("label") self.label.setText(text) self.label.setStyleSheet("padding: 20px") label_spinner = QLabel(Dialog) self.label.setObjectName("label_spinner") label_spinner.setFixedSize(30, 30) spinner = QtWaitingSpinner(label_spinner) spinner.setRoundness(70.0) # spinner.setMinimumTrailOpacity(10.0) # spinner.setTrailFadePercentage(60.0) spinner.setNumberOfLines(15) spinner.setLineLength(8) # spinner.setLineWidth(5) spinner.setInnerRadius(5) # spinner.setRevolutionsPerSecond(2) spinner.setColor(Qt.white) spinner.start() # starts spinning self.label.setAlignment(Qt.AlignCenter) # if icon == True: # horizontalLayout.addWidget(image) horizontalLayout.addWidget(self.label) horizontalLayout.addWidget(label_spinner)
class CustomWidget(QWidget): def __init__(self): super(CustomWidget, self).__init__() self.widget_layout = QHBoxLayout() self.text_label = QLabel() self.chkbox = QCheckBox() self.widget_layout.setSizeConstraint(QLayout.SetFixedSize) self.widget_layout.addWidget(self.chkbox) self.widget_layout.addStretch() self.widget_layout.setSpacing(20) self.widget_layout.addWidget(self.text_label) self.setLayout(self.widget_layout) def set_text(self, html_txt): self.text_label.setText(html_txt) new_font = QFont("Arial", 10, QFont.Bold) self.text_label.setFont(new_font) self.text_label.adjustSize()
def add_row(self, label_text: QWidget, field_widget: QWidget, stretch_field: bool=False) -> None: line = QFrame() line.setObjectName("PaymentSeparatorLine") line.setFrameShape(QFrame.HLine) line.setFixedHeight(1) self.frame_layout.addWidget(line) label = QLabel(label_text) label.setObjectName("PaymentSectionLabel") label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) help_label = QLabel() help_label.setPixmap( QPixmap(icon_path("icons8-help.svg")).scaledToWidth(16, Qt.SmoothTransformation)) help_label.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum) label_layout = QHBoxLayout() label_layout.addWidget(label) label_layout.addWidget(help_label) # Ensure that the top-aligned vertical spacing matches the fields. label_layout.setContentsMargins(0,2,0,2) label_layout.setSizeConstraint(QLayout.SetFixedSize) grid_layout = QGridLayout() grid_layout.addLayout(label_layout, 0, 0, Qt.AlignLeft | Qt.AlignTop) if stretch_field: grid_layout.addWidget(field_widget, 0, 1) else: field_layout = QHBoxLayout() field_layout.setContentsMargins(0, 0, 0, 0) field_layout.addWidget(field_widget) field_layout.addStretch(1) grid_layout.addLayout(field_layout, 0, 1) grid_layout.setColumnMinimumWidth(0, 80) grid_layout.setColumnStretch(0, 0) grid_layout.setColumnStretch(1, 1) grid_layout.setHorizontalSpacing(0) grid_layout.setSizeConstraint(QLayout.SetMinimumSize) self.frame_layout.addLayout(grid_layout)
class Item(QWidget): def __init__(self, parent=None): super().__init__(parent) self.parent = parent self.name = None self.number = None self.color = self.parent.generateColor() self.layout = QHBoxLayout(self) self.icon = Icon(self) self.input = Input(self) self.setSizePolicy(QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)) self.layout.setSizeConstraint(QLayout.SetMinAndMaxSize) self.setFixedSize(self.parent.parent.sidebarWidth, self.parent.parent.itemHeight) self.layout.setAlignment(Qt.AlignLeft) self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setSpacing(0) self.layout.addWidget(self.icon) self.layout.addWidget(self.input) self.parent.layout.addWidget(self) self.parent.items.append(self) scrollHeight = len(self.parent.items) * self.parent.parent.itemHeight self.parent.setMinimumHeight(scrollHeight) self.parent.scrollArea.verticalScrollBar().setValue(scrollHeight) def showIcon(self, icon: Icon): icon != self.icon.plus and self.icon.plus.hide() icon != self.icon.alert and self.icon.alert.hide() icon != self.icon.circle and self.icon.circle.hide() icon.show() def paintEvent(self, event): o = QStyleOption() o.initFrom(self) p = QPainter(self) self.style().drawPrimitive(QStyle.PE_Widget, o, p, self)
def FillMenuCategories(self): with open(os.path.abspath('JsonFiles/Menus.json'), encoding='utf-8') as f: leftMenuJson = json.load(f) i = 1 self.menuItemCount = len(leftMenuJson.items()) for root, children in leftMenuJson.items(): item = QtWidgets.QListWidgetItem() widget = QWidget() jsonfile = children['jsonfile'] self.jsonFiles.append(children['jsonfile']) self.toolButtons[i] = toolButton = QtWidgets.QToolButton() toolButton.setStyleSheet( "QToolButton {background-color: #394b58; color: white; font: 14pt; padding-top:10px;}\n" "QToolButton:hover {background-color: #6b899f; color: white; font: 14pt; padding-top:10px;}\n") toolButton.setFixedWidth(120) toolButton.setFixedHeight(134) self.toolButtons[1].setStyleSheet("background-color: #6b899f; color: white; font: 14pt; padding-top:10px;") self.activeMenu = 1 icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap(children['icon']), QtGui.QIcon.Normal, QtGui.QIcon.Off) toolButton.setIconSize(QtCore.QSize(50, 50)) toolButton.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon) toolButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor)) toolButton.setIcon(icon) toolButton.setText(root) self.toolButtons[i].clicked.connect( lambda checked, index=i, jsonfile=jsonfile: self.MenuActionClick(jsonfile, index)) toolButton.setObjectName("toolButton") toolButton.raise_() widgetLayout = QHBoxLayout() widgetLayout.addWidget(toolButton) widgetLayout.addStretch() widgetLayout.setSizeConstraint(QLayout.SetFixedSize) widgetLayout.setContentsMargins(0, 0, 0, 0) widget.setLayout(widgetLayout) item.setSizeHint(widget.sizeHint()) self.listWidget.addItem(item) self.listWidget.setItemWidget(item, widget) i = i + 1
def addColorItem(colorString, colorInt, string, layout): def selectColor(label): color = QColorDialog.getColor() label.setStyleSheet('QPushButton { background-color: ' + 'rgba' + str(color.getRgb()) + '; border: 1px solid black; }') style = QPalette() style.setColor(colorInt, color) app.setPalette(style) self.updateSettings(string, color.getRgb()) subsub = QHBoxLayout() label = QPushButton('') label.setAutoFillBackground(True) label.setMinimumWidth(55) label.setStyleSheet('QPushButton { background-color: ' + colorString + '; border: 1px solid black; }') label.clicked.connect(lambda: selectColor(label)) textLabel = QLabel(string) textLabel.setMinimumWidth(100) subsub.addWidget(label) subsub.addWidget(textLabel) subsub.setSizeConstraint(QLayout.SetMaximumSize) if layout == 1: subLayout.addLayout(subsub) else: subLayout2.addLayout(subsub)
def create_main_frame(self): self.board_widget = MainTetrisWidget(self, nrows=20, ncols=10, blocksize=25, startfigure=self.figurebank.get_random()) self.board_widget.setFocus() self.control_panel = QFrame(self) self.control_panel.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.control_panel.setFocusPolicy(Qt.NoFocus) self.populate_control_panel() main_layout = QHBoxLayout() main_layout.addWidget(self.board_widget) main_layout.addWidget(self.control_panel) main_layout.setSizeConstraint(QLayout.SetFixedSize) main_frame = QWidget() main_frame.setLayout(main_layout) self.setCentralWidget(main_frame)
def create_main_frame(self): self.board_widget = MainTetrisWidget( self, nrows=20, ncols=10, blocksize=25, startfigure=self.figurebank.get_random()) self.board_widget.setFocus() self.control_panel = QFrame(self) self.control_panel.setFrameStyle(QFrame.Panel | QFrame.Sunken) self.control_panel.setFocusPolicy(Qt.NoFocus) self.populate_control_panel() main_layout = QHBoxLayout() main_layout.addWidget(self.board_widget) main_layout.addWidget(self.control_panel) main_layout.setSizeConstraint(QLayout.SetFixedSize) main_frame = QWidget() main_frame.setLayout(main_layout) self.setCentralWidget(main_frame)
class E5LineEdit(QLineEdit): """ Class implementing a line edit widget showing some inactive text. """ LeftSide = 0 RightSide = 1 def __init__(self, parent=None, inactiveText=""): """ Constructor @param parent reference to the parent widget (QWidget) @param inactiveText text to be shown on inactivity (string) """ super(E5LineEdit, self).__init__(parent) self.setMinimumHeight(22) if qVersion() < "4.7.0": self.__inactiveText = inactiveText else: self.setPlaceholderText(inactiveText) self.__mainLayout = QHBoxLayout(self) self.__mainLayout.setContentsMargins(0, 0, 0, 0) self.__mainLayout.setSpacing(0) self.__leftMargin = 0 self.__leftWidget = E5LineEditSideWidget(self) self.__leftWidget.resize(0, 0) self.__leftLayout = QHBoxLayout(self.__leftWidget) self.__leftLayout.setContentsMargins(0, 0, 2, 0) if QApplication.isRightToLeft(): self.__leftLayout.setDirection(QBoxLayout.RightToLeft) else: self.__leftLayout.setDirection(QBoxLayout.LeftToRight) self.__leftLayout.setSizeConstraint(QLayout.SetFixedSize) self.__rightWidget = E5LineEditSideWidget(self) self.__rightWidget.resize(0, 0) self.__rightLayout = QHBoxLayout(self.__rightWidget) self.__rightLayout.setContentsMargins(0, 0, 2, 0) if self.isRightToLeft(): self.__rightLayout.setDirection(QBoxLayout.RightToLeft) else: self.__rightLayout.setDirection(QBoxLayout.LeftToRight) horizontalSpacer = QSpacerItem( 0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum) self.__mainLayout.addWidget( self.__leftWidget, 0, Qt.AlignVCenter | Qt.AlignLeft) self.__mainLayout.addItem(horizontalSpacer) self.__mainLayout.addWidget( self.__rightWidget, 0, Qt.AlignVCenter | Qt.AlignRight) if self.isRightToLeft(): self.__mainLayout.setDirection(QBoxLayout.RightToLeft) else: self.__mainLayout.setDirection(QBoxLayout.LeftToRight) self.setWidgetSpacing(3) self.__leftWidget.sizeHintChanged.connect(self._updateTextMargins) self.__rightWidget.sizeHintChanged.connect(self._updateTextMargins) def setLeftMargin(self, margin): """ Public method to set the left margin. @param margin left margin in pixel (integer) """ self.__leftMargin = margin def leftMargin(self): """ Public method to get the size of the left margin. @return left margin in pixel (integer) """ return self.__leftMargin def event(self, evt): """ Public method to handle events. @param evt reference to the event (QEvent) @return flag indicating, whether the event was recognized (boolean) """ if evt.type() == QEvent.LayoutDirectionChange: if self.isRightToLeft(): self.__mainLayout.setDirection(QBoxLayout.RightToLeft) self.__leftLayout.setDirection(QBoxLayout.RightToLeft) self.__rightLayout.setDirection(QBoxLayout.RightToLeft) else: self.__mainLayout.setDirection(QBoxLayout.LeftToRight) self.__leftLayout.setDirection(QBoxLayout.LeftToRight) self.__rightLayout.setDirection(QBoxLayout.LeftToRight) return QLineEdit.event(self, evt) def paintEvent(self, evt): """ Protected method handling a paint event. @param evt reference to the paint event (QPaintEvent) """ super(E5LineEdit, self).paintEvent(evt) if qVersion() < "4.7.0": if not self.text() and \ self.__inactiveText and \ not self.hasFocus(): panel = QStyleOptionFrame() self.initStyleOption(panel) textRect = self.style().subElementRect( QStyle.SE_LineEditContents, panel, self) textRect.adjust(2, 0, 0, 0) left = self.textMargin(self.LeftSide) right = self.textMargin(self.RightSide) textRect.adjust(left, 0, -right, 0) painter = QPainter(self) painter.setPen(self.palette().brush( QPalette.Disabled, QPalette.Text).color()) painter.drawText( textRect, Qt.AlignLeft | Qt.AlignVCenter, self.__inactiveText) def _updateTextMargins(self): """ Protected slot to update the text margins. """ if self.__leftMargin == 0: left = self.__leftWidget.sizeHint().width() else: left = self.__leftMargin right = self.__rightWidget.sizeHint().width() top = 0 bottom = 0 self.setTextMargins(left, top, right, bottom) def addWidget(self, widget, position): """ Public method to add a widget to a side. @param widget reference to the widget to add (QWidget) @param position position to add to (E5LineEdit.LeftSide, E5LineEdit.RightSide) """ if widget is None: return if self.isRightToLeft(): if position == self.LeftSide: position = self.RightSide else: position = self.LeftSide if position == self.LeftSide: self.__leftLayout.addWidget(widget) else: self.__rightLayout.insertWidget(1, widget) def removeWidget(self, widget): """ Public method to remove a widget from a side. @param widget reference to the widget to remove (QWidget) """ if widget is None: return self.__leftLayout.removeWidget(widget) self.__rightLayout.removeWidget(widget) widget.hide() def widgetSpacing(self): """ Public method to get the side widget spacing. @return side widget spacing (integer) """ return self.__leftLayout.spacing() def setWidgetSpacing(self, spacing): """ Public method to set the side widget spacing. @param spacing side widget spacing (integer) """ self.__leftLayout.setSpacing(spacing) self.__rightLayout.setSpacing(spacing) self._updateTextMargins() def textMargin(self, position): """ Public method to get the text margin for a side. @param position side to get margin for (E5LineEdit.LeftSide, E5LineEdit.RightSide) @return text margin (integer) """ spacing = self.__rightLayout.spacing() w = 0 if position == self.LeftSide: w = self.__leftWidget.sizeHint().width() else: w = self.__rightWidget.sizeHint().width() if w == 0: return 0 return w + spacing * 2 def inactiveText(self): """ Public method to get the inactive text. @return inactive text (string) """ if qVersion() < "4.7.0": return self.__inactiveText else: return self.placeholderText() def setInactiveText(self, inactiveText): """ Public method to set the inactive text. @param inactiveText text to be shown on inactivity (string) """ if qVersion() < "4.7.0": self.__inactiveText = inactiveText self.update() else: self.setPlaceholderText(inactiveText)
class LineEdit(QLineEdit): inactiveText = QtDynamicProperty('inactiveText', unicode) widgetSpacing = QtDynamicProperty('widgetSpacing', int) def __init__(self, parent=None, contents=u""): super(LineEdit, self).__init__(contents, parent) box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight self.inactiveText = u"" self.left_widget = SideWidget(self) self.left_widget.resize(0, 0) self.left_layout = QHBoxLayout(self.left_widget) self.left_layout.setContentsMargins(0, 0, 0, 0) self.left_layout.setDirection(box_direction) self.left_layout.setSizeConstraint(QLayout.SetFixedSize) self.right_widget = SideWidget(self) self.right_widget.resize(0, 0) self.right_layout = QHBoxLayout(self.right_widget) self.right_layout.setContentsMargins(0, 0, 0, 0) self.right_layout.setDirection(box_direction) self.right_layout.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)) self.widgetSpacing = 2 self.left_widget.sizeHintChanged.connect(self._update_text_margins) self.right_widget.sizeHintChanged.connect(self._update_text_margins) @property def left_margin(self): return self.left_widget.sizeHint().width() + 2*self.left_layout.spacing() @property def right_margin(self): return self.right_widget.sizeHint().width() + 2*self.right_layout.spacing() def _update_text_margins(self): self.setTextMargins(self.left_margin, 0, self.right_margin, 0) self._update_side_widget_locations() def _update_side_widget_locations(self): option = QStyleOptionFrame() self.initStyleOption(option) spacing = self.right_layout.spacing() text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, option, self) text_rect.adjust(spacing, 0, -spacing, 0) mid_height = text_rect.center().y() + 1 - (text_rect.height() % 2) # need -1 correction for odd heights -Dan if self.left_layout.count() > 0: left_height = mid_height - self.left_widget.height()/2 left_width = self.left_widget.width() if left_width == 0: left_height = mid_height - self.left_widget.sizeHint().height()/2 self.left_widget.move(text_rect.x(), left_height) text_rect.setX(self.left_margin) text_rect.setY(mid_height - self.right_widget.sizeHint().height()/2.0) text_rect.setHeight(self.right_widget.sizeHint().height()) self.right_widget.setGeometry(text_rect) def event(self, event): event_type = event.type() if event_type == QEvent.LayoutDirectionChange: box_direction = QBoxLayout.RightToLeft if self.isRightToLeft() else QBoxLayout.LeftToRight self.left_layout.setDirection(box_direction) self.right_layout.setDirection(box_direction) elif event_type == QEvent.DynamicPropertyChange: property_name = event.propertyName() if property_name == 'widgetSpacing': self.left_layout.setSpacing(self.widgetSpacing) self.right_layout.setSpacing(self.widgetSpacing) self._update_text_margins() elif property_name == 'inactiveText': self.update() return QLineEdit.event(self, event) def resizeEvent(self, event): self._update_side_widget_locations() QLineEdit.resizeEvent(self, event) def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not self.hasFocus() and not self.text() and self.inactiveText: options = QStyleOptionFrame() self.initStyleOption(options) text_rect = self.style().subElementRect(QStyle.SE_LineEditContents, options, self) text_rect.adjust(self.left_margin+2, 0, -self.right_margin, 0) painter = QPainter(self) painter.setPen(self.palette().brush(QPalette.Disabled, QPalette.Text).color()) painter.drawText(text_rect, Qt.AlignLeft | Qt.AlignVCenter, self.inactiveText) def addHeadWidget(self, widget): if self.isRightToLeft(): self.right_layout.insertWidget(1, widget) else: self.left_layout.addWidget(widget) def addTailWidget(self, widget): if self.isRightToLeft(): self.left_layout.addWidget(widget) else: self.right_layout.insertWidget(1, widget) def removeWidget(self, widget): self.left_layout.removeWidget(widget) self.right_layout.removeWidget(widget) widget.hide()
class TcamView(QWidget): image_saved = pyqtSignal(str) video_saved = pyqtSignal(str) new_pixel_under_mouse = pyqtSignal(bool, int, int, QtGui.QColor) current_fps = pyqtSignal(float) format_selected = pyqtSignal(str, str, str) # format, widthxheight, framerate first_image = pyqtSignal() def __init__(self, serial, parent=None): super(TcamView, self).__init__(parent) self.layout = QHBoxLayout() self.container = TcamScreen(self) self.container.new_pixel_under_mouse.connect(self.new_pixel_under_mouse_slot) self.fullscreen_container = None # separate widget for fullscreen usage self.is_fullscreen = False self.layout.addWidget(self.container) self.layout.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize) self.setLayout(self.layout) self.serial = serial self.tcam = None self.pipeline = None self.image = None self.mouse_is_pressed = False self.use_dutils = True self.current_width = 0 self.current_height = 0 self.device_lost_callbacks = [] self.caps_desc = None self.video_format = None self.retry_countdown = 0 self.actual_fps = 0.0 self.framecounter = 0 self.start_time = 0 self.settings = None self.video_fng = None self.image_fng = None # additional timer to update actual_fps # when no images arrive self.fps_timer = QtCore.QTimer() self.fps_timer.timeout.connect(self.fps_tick) self.file_pattern = "" self.file_location = "/tmp" self.caps = None self.videosaver = None self.imagesaver = None def get_caps_desc(self): """ Returns a CapsDesc describing the caps of the currently opened device Returns None if device is not opened """ if not self.caps_desc: tcam = self.get_tcam() if not tcam: return None caps = tcam.get_static_pad("src").query_caps() self.caps_desc = CapsDesc(caps) return self.caps_desc def new_pixel_under_mouse_slot(self, active: bool, mouse_x: int, mouse_y: int, color: QtGui.QColor): self.new_pixel_under_mouse.emit(active, mouse_x, mouse_y, color) def eventFilter(self, obj, event): """""" if event.type == QEvent.KeyPress: if event.key() == Qt.Key_F11: self.toggle_fullscreen() return True return QObject.eventFilter(self, obj, event) def set_settings(self, new_settings: Settings): """ Update settings of all subclasses """ self.settings = new_settings self.use_dutils = self.settings.use_dutils if not self.video_fng: self.video_fng = FileNameGenerator(self.serial, self.settings.video_name) else: self.video_fng.set_settings(self.settings.video_name) self.video_fng.location = self.settings.save_location self.video_fng.file_suffix = get_encoder_dict()[self.settings.video_type].file_ending if not self.image_fng: self.image_fng = FileNameGenerator(self.serial, self.settings.image_name) else: self.image_fng.set_settings(self.settings.image_name) self.image_fng.location = self.settings.save_location self.image_fng.file_suffix = get_encoder_dict()[self.settings.image_type].file_ending def toggle_fullscreen(self): if self.is_fullscreen: self.is_fullscreen = False self.showNormal() self.fullscreen_container.hide() # self.fullscreen_container.deleteLater() self.fullscreen_container = None else: self.is_fullscreen = True self.fullscreen_container = TcamScreen() self.fullscreen_container.is_fullscreen = True self.fullscreen_container.setAttribute(QtCore.Qt.WA_DeleteOnClose) self.fullscreen_container.showFullScreen() self.fullscreen_container.show() self.container.first_image = True self.fullscreen_container.setFocusPolicy(QtCore.Qt.StrongFocus) self.fullscreen_container.installEventFilter(self.fullscreen_container) self.fullscreen_container.destroy_widget.connect(self.toggle_fullscreen) # either show info that we are in trigger mode and still waiting for the first image # or show that last image we had. This way we always have something to show to the user if self.is_trigger_mode_on() and self.container.first_image: self.fullscreen_container.wait_for_first_image() else: self.fullscreen_container.on_new_pixmap(self.container.pix.pixmap()) def fit_view(self): if self.is_fullscreen: self.fullscreen_container.fit_in_view.emit() else: self.container.fit_in_view.emit() def save_image(self, image_type: str): if not self.imagesaver: self.imagesaver = MediaSaver(self.serial, self.caps, MediaType.image) self.imagesaver.saved.connect(self.image_saved_callback) self.imagesaver.error.connect(self.image_error_callback) self.image_fng.set_settings(self.settings.image_name) fn = self.image_fng.create_file_name("image") self.imagesaver.current_filename = fn self.imagesaver.save_image(get_encoder_dict()[image_type]) def image_saved_callback(self, image_path: str): """ SLOT for imagesaver callback for successfull saving """ self.image_saved.emit(image_path) def image_error_callback(self, error_msg: str): pass def video_saved_callback(self, video_path: str): """ SLOT for videosaver callback for successfull saving """ self.video_saved.emit(video_path) def start_recording_video(self, video_type: str): """ """ if self.videosaver: log.error("A video recording is already ongoing.") return self.videosaver = MediaSaver(self.serial, self.caps, MediaType.video) self.videosaver.set_encoder(video_type) self.videosaver.location = self.file_location self.videosaver.current_filename = self.video_fng.create_file_name() self.videosaver.saved.connect(self.video_saved_callback) self.videosaver.start_recording_video(video_type) def stop_recording_video(self): """ """ if self.videosaver: self.videosaver.stop_recording_video() self.videosaver = None def play(self, video_format=None): if self.videosaver: self.stop_recording_video() if self.pipeline is None: self.create_pipeline() self.pipeline.set_state(Gst.State.READY) if video_format: caps_desc = self.get_caps_desc() if caps_desc.contains(video_format): self.video_format = video_format else: log.error("Given format caps could not be found in caps descriptions. {}".format(video_format)) log.error("Falling back to default behavior.") if self.video_format is not None: log.info("Setting format to {}".format(video_format)) caps = self.pipeline.get_by_name("bin") caps.set_property("device-caps", video_format) self.pipeline.set_state(Gst.State.PLAYING) self.start_time = 0 self.framecounter = 0 self.fps_timer.start(1000) # 1 second self.container.first_image = True if self.is_trigger_mode_on(): self.container.wait_for_first_image() def fps_tick(self): """ Recalculate the current fps and emit current_fps signal """ self.framecounter += 1 if self.start_time == 0: self.start_time = time.time() else: diff = int(time.time() - self.start_time) if diff == 0: return self.actual_fps = self.framecounter / diff self.current_fps.emit(self.actual_fps) def new_buffer(self, appsink): """ callback for appsink new-sample signal converts gstbuffer into qpixmap and gives it to the display container """ buf = self.pipeline.get_by_name("sink").emit("pull-sample") caps = buf.get_caps() self.caps = caps struc = caps.get_structure(0) b = buf.get_buffer() try: (ret, buffer_map) = b.map(Gst.MapFlags.READ) if self.current_width == 0: self.current_width = struc.get_value("width") if self.current_height == 0: self.current_height = struc.get_value("height") self.fps_tick() if self.container.first_image: self.first_image.emit() self.image = QtGui.QPixmap.fromImage(QtGui.QImage(buffer_map.data, struc.get_value("width"), struc.get_value("height"), QtGui.QImage.Format_ARGB32)) if self.fullscreen_container is not None: if self.fullscreen_container.isFullScreen(): self.fullscreen_container.new_pixmap.emit(self.image) else: self.container.new_pixmap.emit(self.image) if self.videosaver and self.videosaver.accept_buffer: self.videosaver.feed_image(b) if self.imagesaver and self.imagesaver.accept_buffer: self.imagesaver.feed_image(b) finally: b.unmap(buffer_map) return Gst.FlowReturn.OK def create_pipeline(self, video_format=None): # the queue element before the sink is important. # it allows set_state to work as expected. # the sink is synced with our main thread (the display thread). # changing the state from out main thread will cause a deadlock, # since the remaining buffers can not be displayed because our main thread # is currently in set_state pipeline_str = ("tcambin serial={serial} name=bin use-dutils={dutils} " "! video/x-raw,format=BGRx " "! tee name=tee tee. " "! queue max-size-buffers=2 leaky=downstream " "! videoconvert " "! video/x-raw,format=BGRx " "! appsink name=sink emit-signals=true") self.pipeline = None self.pipeline = Gst.parse_launch(pipeline_str.format(serial=self.serial, dutils=self.use_dutils)) sink = self.pipeline.get_by_name("sink") sink.connect("new-sample", self.new_buffer) # Create bus to get events from GStreamer pipeline self.bus = self.pipeline.get_bus() self.bus.add_signal_watch() self.bus.enable_sync_message_emission() self.bus.connect('message::error', self.on_error) self.bus.connect('message::info', self.on_info) self.tcam = self.pipeline.get_by_name("bin") self.pipeline.set_state(Gst.State.READY) log.debug("Created pipeline and set to READY") def pause(self): log.info("Setting state to PAUSED") if self.pipeline: self.pipeline.set_state(Gst.State.PAUSED) else: log.error("Pipeline object does not exist.") self.start_time = 0 self.framecounter = 0 self.fps_timer.stop() def stop(self): """ Stop playback """ log.info("Setting state to NULL") self.start_time = 0 self.fps_timer.stop() self.pipeline.set_state(Gst.State.NULL) def on_info(self, bus, msg): """ Callback for gst bus info messages """ info, dbg = msg.parse_info() log.info(dbg) if msg.src.get_name() == "bin": if dbg.startswith("Working with src caps:"): log.info("{}".format(dbg.split(": ")[1])) self.fire_format_selected(dbg.split(": ")[1]) else: log.error("Info from bin: {}".format(dbg)) else: log.error("ERROR:", msg.src.get_name()) if dbg: log.debug("Debug info:", dbg) def fire_format_selected(self, caps: str): """ Emit SIGNAL that the pipeline has selected src caps and inform listeners what the caps are """ if caps is None or caps == "NULL": log.error("Bin returned faulty source caps. Not firiing format_selected") return c = Gst.Caps.from_string(caps) if c.is_empty(): log.error("Received empty caps. Aborting fire_format_selected") return structure = c.get_structure(0) self.image_fng.set_caps(c) self.video_fng.set_caps(c) if structure.get_name() == "image/jpeg": fmt = "jpeg" else: fmt = structure.get_value("format") resolution = "{}x{}".format(structure.get_value("width"), structure.get_value("height")) # compatability problems # Older python bindings do not know the type Gst.Fraction. # Thus we have to work around this problem... results = re.search("framerate=\(fraction\)\d+/\d+", caps) if results: fps = results.group() fps = fps.replace("framerate=(fraction)", "") else: fps = None log.error("Unable to determine framerate settings. This will affect usability.") self.format_selected.emit(fmt, resolution, str(fps)) def on_error(self, bus, msg): """ Callback for gst bus messages Receives errors and chooses appropriate actions """ err, dbg = msg.parse_error() if msg.src.get_name() == "tcambin-source": if err: if "Device lost (" in err.message: m = re.search('Device lost \((.*)\)', err.message) log.error("Received device lost message for {}".format(m.group(1))) self.fire_device_lost() else: log.error("Error from source: {}".format(err.message)) self.retry_countdown -= 1 if self.retry_countdown <= 0: log.error("Repeatedly retried to start stream. No Success. Giving up.") return log.info("Trying restart of stream") self.stop() self.play(self.video_format) else: log.error("ERROR: {} : {}".format(msg.src.get_name(), err.message)) if dbg: log.debug("Debug info: {}".format(dbg)) def get_tcam(self): return self.tcam def register_device_lost(self, callback): self.device_lost_callbacks.append(callback) def fire_device_lost(self): """ Notify all callback that our device is gone """ for cb in self.device_lost_callbacks: cb() def is_trigger_mode_on(self): if not self.tcam: return False try: (result, value, minval, maxval, defval, step, valuetype, flags, category, group) = self.tcam.get_tcam_property("Trigger Mode") except TypeError as e: log.warning("get_tcam_property failed for '{}'".format("Trigger Mode")) return False if valuetype == "boolean": if value: return True return False elif valuetype == "enum": if value == "On": return True return True def trigger_image(self): """ Checks if trigger mode is active and try to trigger an image """ if self.is_trigger_mode_on(): self.tcam.set_tcam_property("Software Trigger", True) def start_roi_capture(self, finished_signal): """ Start capturing a ROI and emit finished_signal once the capture is finished """ self.container.start_roi_capture(finished_signal) def add_roi(self, roi_widget): """ Add the given roi_widget for permanent display. Call remove_roi to undo. """ self.container.add_roi(roi_widget) def remove_roi(self, roi_widget): """ Remove roi_widget from display """ self.container.remove_roi(roi_widget) @staticmethod def has_dutils(): """ Check to see if the gstreamer module gsttcamdutils is available. """ factory = Gst.ElementFactory.find("tcamdutils") if factory: return True return False