# PyQt5==5.12
from PyQt5.QtCore import Qt, QPropertyAnimation, QSize, QTimer
from PyQt5.QtGui import QIcon, QPixmap, QPainter, QPaintEvent, QBrush
from PyQt5.QtWidgets import QMainWindow, QMessageBox, QStackedWidget, QDesktopWidget, QHBoxLayout, QWidget, QLabel, \
QSizePolicy, QFileDialog
class Toast(QWidget):
style = """#LabelMessage{color:white;font-family:Microsoft YaHei;}"""
def __init__(self, message='', timeout=2000, parent=None):
"""
@param message: 提示信息
@param timeout: 窗口显示时长
@param parent: 父窗口控件
"""
super(Toast, self).__init__()
self.parent = parent
# 除了成功之外其他消息图标一律使用错误图标(有局限性:成功的具体信息有很多种,但这里没办法区分,待改)
self.timer = QTimer()
# 由于不知道动画结束的事件,所以借助QTimer来关闭窗口,动画结束就关闭窗口,所以这里的事件要和动画时间一样
self.timer.singleShot(timeout, self.close) # singleShot表示timer只会启动一次
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)
# self.setWindowOpacity(0.9) # 设置窗口透明度
self.setAttribute(Qt.WA_TranslucentBackground) # 设置窗口透明
self.setObjectName('Toast')
# self.setFixedSize(QSize(220, 100))
self.setMinimumSize(QSize(220, 100))
self.setMaximumSize(QSize(220, 180))
layout = QHBoxLayout()
layout.setContentsMargins(20, -1, 20, -1)
layout.setObjectName("HorizontalLayout")
self.setLayout(layout)
self.initUi(layout, message)
self.createAnimation(timeout)
self.setStyleSheet(Toast.style)
self.center()
def initUi(self, layout, message):
messageLabel = QLabel()
# 实现QLabel自动换行
sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(messageLabel.sizePolicy().hasHeightForWidth())
messageLabel.setSizePolicy(sizePolicy)
messageLabel.setWordWrap(True)
messageLabel.setText(message)
messageLabel.setTextFormat(Qt.AutoText)
messageLabel.setScaledContents(True)
messageLabel.setObjectName("LabelMessage")
messageLabel.setAlignment(Qt.AlignCenter)
layout.addWidget(messageLabel)
def paintEvent(self, a0: QPaintEvent):
qp = QPainter()
qp.begin(self) # 不能掉,不然没效果
qp.setRenderHints(QPainter.Antialiasing, True) # 抗锯齿
qp.setBrush(QBrush(Qt.black))
qp.setPen(Qt.transparent)
rect = self.rect()
rect.setWidth(rect.width() - 1)
rect.setHeight(rect.height() - 1)
qp.drawRoundedRect(rect, 15, 15)
qp.end()
def createAnimation(self, timeout):
# 1.定义一个动画
self.animation = QPropertyAnimation(self, b'windowOpacity')
self.animation.setTargetObject(self)
# 2.设置属性值
self.animation.setStartValue(0)
self.animation.setKeyValueAt(0.2, 0.7) # 设置插值0.3 表示单本次动画时间的0.3处的时间点
self.animation.setKeyValueAt(0.8, 0.7) # 设置插值0.8 表示单本次动画时间的0.3处的时间点
self.animation.setEndValue(0)
# 3.设置时长
self.animation.setDuration(timeout)
# 4.启动动画
self.animation.start()
def center(self):
if self.parent is not None:
xPos = self.parent.x() + int((self.parent.width() - self.width()) / 2)
yPos = self.parent.y() + int((self.parent.height() - self.height()) / 2 + 40)
self.move(xPos, yPos)
else:
# 屏幕居中
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move(int((screen.width() - size.width()) / 2),
int((screen.height() - size.height()) / 2) + 40)
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow, self).__init__()
self.setWindowTitle("分析工具") # 设置窗口标题
self.setWindowFlags(self.windowFlags() & ~Qt.WindowMaximizeButtonHint) # 禁止最大化按钮
self.setWindowIcon(QIcon(LOGO_PATH)) # 设置窗口图标,icon.png 是您的图标文件路径
self.stacked_widget = QStackedWidget() # 创建堆叠窗口
self.setCentralWidget(self.stacked_widget)
self.shouye = self.load_ui(SHOUYE_UI) # 绑定首页UI
self.fenxizhong = self.load_ui(FENXIZHONG_UI) # 分析中UI
self.shenqingqushi = self.load_ui(SHENQINGQUSHI_UI) # 申请趋势
self.bujudiyu = self.load_ui(BUJUDIYU_UI) # 布局地域分析
self.bujudiyu_shijiantaishi = self.load_ui(BUJUDIYU_SHIJIANTAISHI_UI) # 布局地域时间态势分析
self.jishulingyu_zhanbi = self.load_ui(JISHULINGYU_ZHANBI_UI) # 技术领域占比分析
self.jishulingyu_shijiantaishi = self.load_ui(JISHULINGYU_SHIJIANTAISHI_UI) # 技术领域时间态势分析
self.famingrenguanxi = self.load_ui(FAMINGRENGUANXI_UI) # 发明人关系
self.jishulingyu = self.load_ui(JISHULINGYU_UI) # 技术领域
self.switch_to_shouye() # 初始化页面到首页
self.binding_redirect()
self.xlsx_path = None # 选择xlsx文件绝对路径
def showToast(self, message):
Toast(message, parent=self).show()
def open_file_dialog(self):
'''xlsx文件选择器'''
file_path, _ = QFileDialog.getOpenFileName(self, '选择文件', '', 'Excel Files (*.xlsx)',
options=QFileDialog.Options())
if file_path:
logger.debug(f'excel文件选择为:【{file_path}】')
self.xlsx_path = file_path
self.shouye.label_6.setText(f'文件:{file_path}')
def switch_to_shouye(self):
'''切换首页'''
self.stacked_widget.setCurrentWidget(self.shouye)
self.shouye.label_2.setPixmap(QPixmap(UPLOAD_PATH)) # 加载上传的云朵图标
self.shouye.lineEdit_6.setFocus() # 给公司信息输入框获取焦点
self.shouye.pushButton_17.clicked.connect(self.open_file_dialog) # 选择文件
def switch_to_fenxizhong(self):
'''切换分析中'''
self.stacked_widget.setCurrentWidget(self.fenxizhong)
_async(target=self.progress_bar).start()
def switch_to_shenqingqushi(self):
'''切换申请趋势'''
self.stacked_widget.setCurrentWidget(self.shenqingqushi)
def switch_to_bujudiyu(self):
'''切换布局地域分析'''
self.stacked_widget.setCurrentWidget(self.bujudiyu)
def switch_to_bujudiyu_shijiantaishi(self):
'''切换布局地域时间态势分析'''
self.stacked_widget.setCurrentWidget(self.bujudiyu_shijiantaishi)
def switch_to_jishulingyu_zhanbi(self):
'''切换技术领域占比分析'''
self.stacked_widget.setCurrentWidget(self.jishulingyu_zhanbi)
def switch_to_jishulingyu_shijiantaishi(self):
'''切换技术领域时间态势分析'''
self.stacked_widget.setCurrentWidget(self.jishulingyu_shijiantaishi)
def switch_to_famingrenguanxi(self):
'''切换发明人关系'''
self.stacked_widget.setCurrentWidget(self.famingrenguanxi)
def swich_to_jishulingyu(self):
'''切换技术领域'''
self.stacked_widget.setCurrentWidget(self.jishulingyu)
def progress_bar(self):
'''进度条'''
for i in range(1, 101):
self.fenxizhong.progressBar.setValue(i)
time.sleep(0.01)
time.sleep(0.5)
self.switch_to_shenqingqushi()
def binding_redirect(self):
'''绑定跳转关系'''
menu_url = [self.shenqingqushi, self.bujudiyu, self.bujudiyu_shijiantaishi, self.jishulingyu_zhanbi,
self.jishulingyu_shijiantaishi, self.famingrenguanxi, self.jishulingyu]
menu_button = [f'pushButton_{num}' for num in range(21, 28)]
url_func = [self.switch_to_shenqingqushi, self.switch_to_bujudiyu, self.switch_to_bujudiyu_shijiantaishi,
self.switch_to_jishulingyu_zhanbi, self.switch_to_jishulingyu_shijiantaishi,
self.switch_to_famingrenguanxi, self.swich_to_jishulingyu]
for url in menu_url:
for index, menu in enumerate(menu_button):
getattr(url, menu).clicked.connect(url_func[index])
def closeEvent(self, event):
'''窗口被关闭事件'''
msgBox = CustomMessageBox()
msgBox.setWindowTitle('分析工具')
msgBox.setText('您确认关闭系统吗?')
msgBox.addButton(QMessageBox.Yes)
msgBox.addButton(QMessageBox.No)
yes_button = msgBox.button(QMessageBox.Yes)
yes_button.setText('是')
no_button = msgBox.button(QMessageBox.No)
no_button.setText('否')
reply = msgBox.exec_() # 显示消息框,并等待用户的响应
if reply == QMessageBox.Yes:
event.accept()
else:
event.ignore() # 忽略关闭事件
def load_ui(self, path):
'''加载UI'''
ui = loadUi(path)
self.stacked_widget.addWidget(ui)
return ui
class LogicViews(MyWindow):
'''逻辑执行'''
def __init__(self):
super().__init__()
self.shouye.pushButton_18.clicked.connect(self.shouye_views) # 点击首页开始分析
def shouye_views(self):
'''首页逻辑'''
corporate_name = self.shouye.lineEdit_6.text()
if corporate_name in ('', None):
return self.showToast('公司名称不可为空')
elif self.xlsx_path is None:
return self.showToast('请先上传文件')
self.switch_to_fenxizhong()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = LogicViews()
window.showMaximized()
window.show()
sys.exit(app.exec_())
pyqt -- 实现Toast/多页面跳转/弹框
于 2024-07-10 12:02:36 首次发布