def scale_image(data, width=60, height=80, compression_quality=70, as_png=False, preserve_aspect_ratio=True): ''' Scale an image, returning it as either JPEG or PNG data (bytestring). Transparency is alpha blended with white when converting to JPEG. Is thread safe and does not require a QApplication. ''' # We use Qt instead of ImageMagick here because ImageMagick seems to use # some kind of memory pool, causing memory consumption to sky rocket. if isinstance(data, QImage): img = data else: img = QImage() if not img.loadFromData(data): raise ValueError('Could not load image for thumbnail generation') if preserve_aspect_ratio: scaled, nwidth, nheight = fit_image(img.width(), img.height(), width, height) if scaled: img = img.scaled(nwidth, nheight, Qt.KeepAspectRatio, Qt.SmoothTransformation) else: if img.width() != width or img.height() != height: img = img.scaled(width, height, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) if not as_png and img.hasAlphaChannel(): nimg = QImage(img.size(), QImage.Format_RGB32) nimg.fill(Qt.white) p = QPainter(nimg) p.drawImage(0, 0, img) p.end() img = nimg ba = QByteArray() buf = QBuffer(ba) buf.open(QBuffer.WriteOnly) fmt = 'PNG' if as_png else 'JPEG' if not img.save(buf, fmt, quality=compression_quality): raise ValueError('Failed to export thumbnail image to: ' + fmt) return img.width(), img.height(), ba.data()
def render_cover(self, book_id): if self.ignore_render_requests.is_set(): return tcdata, timestamp = self.thumbnail_cache[book_id] use_cache = False if timestamp is None: # Not in cache has_cover, cdata, timestamp = self.model( ).db.new_api.cover_or_cache(book_id, 0) else: has_cover, cdata, timestamp = self.model( ).db.new_api.cover_or_cache(book_id, timestamp) if has_cover and cdata is None: # The cached cover is fresh cdata = tcdata use_cache = True if has_cover: p = QImage() p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG') dpr = self.device_pixel_ratio p.setDevicePixelRatio(dpr) if p.isNull() and cdata is tcdata: # Invalid image in cache self.thumbnail_cache.invalidate((book_id, )) self.update_item.emit(book_id) return cdata = None if p.isNull() else p if not use_cache: # cache is stale if cdata is not None: width, height = p.width(), p.height() scaled, nwidth, nheight = fit_image( width, height, int(dpr * self.delegate.cover_size.width()), int(dpr * self.delegate.cover_size.height())) if scaled: if self.ignore_render_requests.is_set(): return p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) p.setDevicePixelRatio(dpr) cdata = p # update cache if cdata is None: self.thumbnail_cache.invalidate((book_id, )) else: try: self.thumbnail_cache.insert(book_id, timestamp, image_to_data(cdata)) except EncodeError as err: self.thumbnail_cache.invalidate((book_id, )) prints(err) except Exception: import traceback traceback.print_exc() elif tcdata is not None: # Cover was removed, but it exists in cache, remove from cache self.thumbnail_cache.invalidate((book_id, )) self.delegate.cover_cache.set(book_id, cdata) self.update_item.emit(book_id)
def get_icon(path, pixmap_to_data=None, as_data=False, size=64): if not path: return with TemporaryDirectory() as tdir: iconset = os.path.join(tdir, 'output.iconset') try: subprocess.check_call( ['iconutil', '-c', 'iconset', '-o', 'output.iconset', path], cwd=tdir) except subprocess.CalledProcessError: return try: names = os.listdir(iconset) except EnvironmentError: return if not names: return from PyQt5.Qt import QImage, Qt names.sort(key=numeric_sort_key) for name in names: m = re.search(r'(\d+)x\d+', name) if m is not None and int(m.group(1)) >= size: ans = QImage(os.path.join(iconset, name)) if not ans.isNull(): break else: return ans = ans.scaled(size, size, transformMode=Qt.SmoothTransformation) if as_data: ans = pixmap_to_data(ans) return ans
def get_icon(path, pixmap_to_data=None, as_data=False, size=64): if not path: return with TemporaryDirectory() as tdir: iconset = os.path.join(tdir, 'output.iconset') try: subprocess.check_call(['iconutil', '-c', 'iconset', '-o', 'output.iconset', path], cwd=tdir) except subprocess.CalledProcessError: return try: names = os.listdir(iconset) except EnvironmentError: return if not names: return from PyQt5.Qt import QImage, Qt names.sort(key=numeric_sort_key) for name in names: m = re.search('(\d+)x\d+', name) if m is not None and int(m.group(1)) >= size: ans = QImage(os.path.join(iconset, name)) if not ans.isNull(): break else: return ans = ans.scaled(size, size, transformMode=Qt.SmoothTransformation) if as_data: ans = pixmap_to_data(ans) return ans
def render_cover(self, book_id): if self.ignore_render_requests.is_set(): return dpr = self.device_pixel_ratio page_width = int(dpr * self.delegate.cover_size.width()) page_height = int(dpr * self.delegate.cover_size.height()) tcdata, timestamp = self.thumbnail_cache[book_id] use_cache = False if timestamp is None: # Not in cache has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, 0) else: has_cover, cdata, timestamp = self.model().db.new_api.cover_or_cache(book_id, timestamp) if has_cover and cdata is None: # The cached cover is fresh cdata = tcdata use_cache = True if has_cover: p = QImage() p.loadFromData(cdata, CACHE_FORMAT if cdata is tcdata else 'JPEG') p.setDevicePixelRatio(dpr) if p.isNull() and cdata is tcdata: # Invalid image in cache self.thumbnail_cache.invalidate((book_id,)) self.update_item.emit(book_id) return cdata = None if p.isNull() else p if not use_cache: # cache is stale if cdata is not None: width, height = p.width(), p.height() scaled, nwidth, nheight = fit_image( width, height, page_width, page_height) if scaled: if self.ignore_render_requests.is_set(): return p = p.scaled(nwidth, nheight, Qt.IgnoreAspectRatio, Qt.SmoothTransformation) p.setDevicePixelRatio(dpr) cdata = p # update cache if cdata is None: self.thumbnail_cache.invalidate((book_id,)) else: try: self.thumbnail_cache.insert(book_id, timestamp, image_to_data(cdata)) except EncodeError as err: self.thumbnail_cache.invalidate((book_id,)) prints(err) except Exception: import traceback traceback.print_exc() elif tcdata is not None: # Cover was removed, but it exists in cache, remove from cache self.thumbnail_cache.invalidate((book_id,)) self.delegate.cover_cache.set(book_id, cdata) self.update_item.emit(book_id)
def update_image(self, array: np.ndarray): im = cv2.transpose(array) im = im.transpose((1, 0, 2)).copy() image = QImage(im, im.shape[1], im.shape[0], QImage.Format_RGB888) palette = self.widget.palette() image = image.scaled(self.widget.geometry().width(), self.widget.geometry().height()) palette.setBrush(QPalette.Background, QBrush(image)) self.widget.setPalette(palette) self.widget.update()
def update_image(self): w, h, c, dt = get_pic(10) if not isinstance(dt, bytes): return # array = np.frombuffer(dt, dtype=np.uint8).reshape((h, w, c)) # array = array.transpose((1, 0, 2)).copy() # array = cv2.transpose(array) # cv2.imshow("aa", array) image = QImage(dt, w, h, QImage.Format_RGB888) palette = self.widget.palette() image = image.scaled(self.widget.geometry().width(), self.widget.geometry().height()) palette.setBrush(QPalette.Background, QBrush(image)) self.widget.setPalette(palette) self.widget.update()
def init_ui(self): width = 800 height = 580 self.setFixedSize(width, height) # 设置棋盘背景 oBackGroundImage = QImage("reversi_images/board.png") sBackGroundImage = oBackGroundImage.scaled(QSize( width, height)) # resize Image to widgets size palette = QPalette() palette.setBrush(QPalette.Window, QBrush(sBackGroundImage)) self.setPalette(palette) # 初始化棋盘元素 self.label_count_down = QLabel('', self) self.label_count_down.setStyleSheet( f"color: orange; font-size: 30px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_count_down.setGeometry(350, 0, 500, 60) self.label_turn = QLabel('蓝方回合', self) self.label_turn.setStyleSheet( f"color: blue; font-size: 24px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_turn.setGeometry(320, 60, 500, 40) self.label_blue_name = QLabel('蓝方-AI托管', self) self.label_blue_name.setStyleSheet( f"color: gray; font-size: 18px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_blue_name.setGeometry(150, 40, 180, 20) self.label_blue_score = QLabel('2', self) self.label_blue_score.setStyleSheet( f"color: yellow; font-size: 24px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_blue_score.setGeometry(180, 60, 120, 30) self.label_red_name = QLabel('大师南瓜球', self) self.label_red_name.setStyleSheet( f"color: gray; font-size: 18px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_red_name.setGeometry(520, 40, 180, 20) self.label_red_score = QLabel('2', self) self.label_red_score.setStyleSheet( f"color: yellow; font-size: 24px; font-weight: bold; font-family: Microsoft YaHei" ) self.label_red_score.setGeometry(570, 60, 120, 30) self.btn_manunal_bye = QPushButton('手动轮空', self) self.btn_manunal_bye.setStyleSheet( f"color: #cf8160; font-size: 18px; font-weight: bold; font-family: Microsoft YaHei; background-color: #89090a" ) self.btn_manunal_bye.setGeometry(685, 460, 80, 30) self.btn_manunal_bye.clicked.connect(self.manunal_bye) self.btn_restart = QPushButton('重新开始', self) self.btn_restart.setStyleSheet( f"color: #cf8160; font-size: 18px; font-weight: bold; font-family: Microsoft YaHei; background-color: #89090a" ) self.btn_restart.setGeometry(685, 505, 80, 30) self.btn_restart.clicked.connect(self.restart) # 180 120 # 445 -> 480 (row 1 -> 8 top ) mid_top_x, mid_top_y = 400, 120 self.btn_list_board = [] self.qicon_blue = QIcon(QPixmap("reversi_images/blue.png")) self.qicon_red = QIcon(QPixmap("reversi_images/red.png")) self.qicon_empty = QIcon() self.qicon_next_step = QIcon(QPixmap("reversi_images/next_step.png")) self.qicon_invalid = QIcon(QPixmap("reversi_images/invalid.png")) self.qicon_current_blue = QIcon( QPixmap("reversi_images/current_blue.png")) self.qicon_current_red = QIcon( QPixmap("reversi_images/current_red.png")) for row_index in range_from_one(board_size): label_row = [] row_width = 445 + int((480 - 445) / 7 * (row_index - 1)) for col_index in range_from_one(board_size): cell = self.board[row_index][col_index] x, y = mid_top_x - row_width // 2 + row_width // 8 * ( col_index - 1), mid_top_y + 47 * (row_index - 1) btn = QPushButton(self) btn.setIconSize(QSize(60, 50)) btn.setGeometry(x, y, row_width // 8, 50) btn.setStyleSheet( "QPushButton { background-color: transparent; border: 0px }" ) def cb(ri, ci): def _cb(): logger.debug(f"clicked row={ri}, col={ci}") # 初始化无效格子 if self.invalid_cell_count < invalid_cell_count: if self.board[ri][ci] != cell_empty: logger.info("该格子不为空,不能设置为无效格子") return self.board[ri][ci] = cell_invalid self.invalid_cell_count = self.invalid_cell_count + 1 logger.info(f"设置第{self.invalid_cell_count}个无效位置") self.paint() if self.invalid_cell_count == invalid_cell_count: # 记录点击次数,到达五个按钮时进入正式游戏模式(尝试ai点击)并隐藏提示按钮 self.ai_try_put_cell() return if self.current_step_cell( ) in self.ai_cells and not self.ai_moving: logger.info("当前回合由机器人托管,将无视该点击") return self.ai_moving = False # 判断是否可行 if self.is_game_over(): self.game_over() return if not self.has_any_valid_cell(): logger.info("本轮无任何可行落子,将轮空") self.next_turn() self.loop_index += 1 if not self.has_any_valid_cell(): logger.info("双方均不可再落子,游戏结束") self.game_over() return # 记录下当前方 current_step_cell = self.current_step_cell() # 落子 is_valid = self.put_cell(ri, ci) is not None if is_valid: self.loop_index += 1 # 计算落子后当前方局面分 current_score = self.evaluate(current_step_cell) if current_score >= 0: cr = "bold_red" else: cr = "bold_green" logger.info( color(cr) + f"落子后当前{self.cell_name_without_color(current_step_cell)}局面分为{current_score}" ) # 重绘界面 self.paint() # 若轮到机器人 self.ai_try_put_cell() return _cb btn.clicked.connect(cb(row_index, col_index)) label_row.append(btn) self.btn_list_board.append(label_row) self.paint() self.show()
class DBSample(QMainWindow): def __init__(self): super().__init__() uic.loadUi('UI1.ui', self) self.setWindowTitle('Sql Reader') self.connection = sqlite3.connect("Res\\logs.db") self.pushButton.clicked.connect(self.select_data) self.horizontalSlider.valueChanged[int].connect(self.changeValue) self.comboBox.addItems(["White", "Dark", "Yarik's Orientation"]) self.comboBox.activated[str].connect(self.themes) self.themes('White') self.textEdit.setPlainText("SELECT * FROM Action") self.error = 0 def select_data(self): query = self.textEdit.toPlainText() if 'order by' not in str(query).lower(): query += ' order by "data time" desc' try: self.error = 0 res = self.connection.cursor().execute(query).fetchall() except: self.error = 1 self.label_3.setText('Sql request Error') self.tableWidget.setColumnCount(3) self.tableWidget.setHorizontalHeaderLabels( ['Action', 'Message', 'Data Time']) self.tableWidget.setColumnWidth(0, 150) self.tableWidget.setColumnWidth(1, 473) if self.error != 1: self.tableWidget.setColumnWidth(2, 110) else: self.tableWidget.setColumnWidth(2, 149) self.tableWidget.setRowCount(0) try: self.error = 0 for i, row in enumerate(res): self.tableWidget.setRowCount(self.tableWidget.rowCount() + 1) for j, elem in enumerate(row): self.tableWidget.setItem(i, j, QTableWidgetItem(str(elem))) self.error = 0 except: self.error = 1 self.label_3.setText('Sql request Error') def themes(self, text): if text == "Yarik's Orientation": self.label.setStyleSheet("color: rgb(0, 0, 0);") self.label_2.setStyleSheet("color: rgb(0, 0, 0);") self.label_3.setStyleSheet("color: rgb(0, 0, 0);") self.label_5.setStyleSheet("color: rgb(0, 0, 0);") self.pushButton.setStyleSheet( "background-image: url('Res/Timber.jpg');border-radius: 10px;") self.textEdit.setStyleSheet("background-image: url(Res/input.jpg)") self.Image = QImage("Res\\Azure Pop.jpg") self.Image = self.Image.scaled(QSize(800, 600)) self.palette = QPalette() self.palette.setBrush(10, QBrush(self.Image)) self.setPalette(self.palette) self.tableWidget.setStyleSheet( 'background-image: url(Res/table.jpg)') stylesheet = """ QTableWidget {background-image: url(Res/table.jpg)} QTableWidget QHeaderView::section:horizontal:first {background-image: url(Res/table0.jpg); border: none; border-style: none;} QTableWidget QHeaderView::section:horizontal:middle {background-image: url(Res/table1.jpg); border: none; border-style: none;} QTableWidget QHeaderView::section:horizontal:last {background-image: url(Res/table2.jpg); border: none; border-style: none;} QTableWidget QHeaderView::section:vertical {background-image: url(Res/table.jpg); border: none; border-style: none;} QTableWidget QTableCornerButton::section {background-image: url(Res/table.jpg); border: 0px} """ self.tableWidget.setStyleSheet(stylesheet) elif text == "Dark": self.label.setStyleSheet("color: rgb(235, 235, 235);") self.label_2.setStyleSheet("color: rgb(235, 235, 235);") self.label_3.setStyleSheet("color: rgb(235, 235, 235);") self.label_5.setStyleSheet("color: rgb(235, 235, 235);") self.pushButton.setStyleSheet( "background-color: white;border-radius: 10px;") self.textEdit.setStyleSheet( "color: rgb(235, 235, 235); background-color: rgb(50, 50, 50)") self.palette = QPalette() self.palette.setBrush(10, QBrush(QColor(27, 27, 27))) self.setPalette(self.palette) stylesheet = """ QTableWidget {color: rgb(235, 235, 235); background-color: rgb(50, 50, 50)} QTableWidget QHeaderView::section {background-color: rgb(50, 50, 50); border: none; border-style: none;} QTableWidget QHeaderView {color: rgb(235, 235, 235);background-color: rgb(50, 50, 50); border: none; border-style: none;} QTableWidget QTableCornerButton::section {background-color: rgb(50, 50, 50); border: 0px} """ self.tableWidget.setStyleSheet(stylesheet) elif text == "White": self.label.setStyleSheet("color: rgb(0, 0, 0);") self.label_2.setStyleSheet("color: rgb(0, 0, 0);") self.label_3.setStyleSheet("color: rgb(0, 0, 0);") self.label_5.setStyleSheet("color: rgb(0, 0, 0);") self.pushButton.setStyleSheet( "background-color: rgb(255, 255, 255);border-radius: 10px;") self.textEdit.setStyleSheet("background-color: rgb(255, 255, 255)") self.palette = QPalette() self.palette.setBrush(10, QBrush(QColor(240, 240, 240))) self.setPalette(self.palette) stylesheet = """ QTableWidget {background-color: rgb(255, 255, 255)} QTableWidget QHeaderView::section {background-color: rgb(255, 255, 255); border: none; border-style: none;} QTableWidget QHeaderView {background-color: rgb(255, 255, 255); border: none; border-style: none;} QTableWidget QTableCornerButton::section {background-color: rgb(255, 255, 255); border: 0px} """ self.tableWidget.setStyleSheet(stylesheet) def changeValue(self, value): self.setWindowOpacity(value / 100) def closeEvent(self, event): self.connection.close()
def set_misc(self): self.retranslateUi(MainWindow) self.pushButton.clicked.connect(self.new_forecast) self.pushButton.setShortcut("Return") QtCore.QMetaObject.connectSlotsByName(MainWindow) oImage = QImage("icons\\background.png") sImage = oImage.scaled(QSize(749, 733)) palette = QPalette() palette.setBrush(10, QBrush(oImage)) MainWindow.setPalette(palette) color = QColor(255, 0, 0, 0) palette = QPalette() palette.setBrush(10, QBrush(color)) self.hForecastSA1.setPalette(palette) self.hForecastSA2.setPalette(palette) self.scrollArea_1.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.scrollArea_1.setFrameShape(QtGui.QFrame.NoFrame) self.scrollArea_2.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.scrollArea_2.setFrameShape(QtGui.QFrame.NoFrame) sAreaStyleSheet = """ QScrollArea{ background-color:transparent; } """ sBarStyleSheet = """ QScrollBar:horizontal{ background-color:transparent; } """ lineEditStyleSheet = """ *{ background-color: rgba(0, 0, 0, 50); color: white; } """ pushButtonStyleSheet = """ *{ background-color: rgba(0, 0, 0, 50); color: white; } """ self.scrollArea_1.setStyleSheet(sAreaStyleSheet) self.scrollArea_1.horizontalScrollBar().setStyleSheet(sBarStyleSheet) self.scrollArea_2.setStyleSheet(sAreaStyleSheet) self.scrollArea_2.horizontalScrollBar().setStyleSheet(sBarStyleSheet) self.lineEdit.setStyleSheet(lineEditStyleSheet) self.pushButton.setStyleSheet(pushButtonStyleSheet)