python:PyQt5 開發一個郵件客戶端,能編寫郵件,發送郵件及附件

PyQt5 郵件客戶端

下面是一個簡潔高效的郵件客戶端實現,支持編寫郵件、添加附件和發送郵件功能:
編寫 eMailClient_qt.py 如下

# -*- coding: utf-8 -*-
""" 用 PyQt5 開發一個郵件客戶端,能編寫郵件,發送郵件及附件 """
import os
import sys
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QFileDialog,QLineEdit, QTextEdit, QPushButton, QLabel,QListWidget, QMessageBox, QStatusBar, QGridLayout)
from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtCore import Qt, QSizeclass EmailClient(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("郵件客戶端")# 設置窗口大小為1000x600self.setGeometry(100, 100, 1000, 600)# 設置現代化UI樣式self.setStyleSheet("""QMainWindow {background-color: #f0f2f5;}QLabel {color: #333;font-size: 12px;font-weight: bold;padding: 2px 0;}QLineEdit, QTextEdit {background-color: white;border: 1px solid #dcdfe6;border-radius: 4px;padding: 8px;font-size: 13px;}QLineEdit:focus, QTextEdit:focus {border: 1px solid #4a90e2;}QPushButton {background-color: #4a90e2;color: white;border: none;border-radius: 4px;padding: 8px 15px;font-size: 13px;min-height: 30px;}QPushButton:hover {background-color: #3a7bc8;}QPushButton:pressed {background-color: #2a65a8;}QPushButton#attachButton {background-color: #f5f7fa;color: #4a90e2;border: 1px solid #4a90e2;}QPushButton#sendButton {background-color: #27ae60;padding: 10px 25px;font-size: 14px;font-weight: bold;}QPushButton#sendButton:hover {background-color: #219653;}QListWidget {background-color: white;border: 1px solid #dcdfe6;border-radius: 4px;padding: 5px;font-size: 12px;alternate-background-color: #f8f9fa;}QStatusBar {background-color: #e0e6ed;color: #666;font-size: 11px;padding: 5px;}QFrame#headerFrame {background-color: #4a90e2;border-radius: 5px;padding: 10px;}""")# 創建中央部件central_widget = QWidget()self.setCentralWidget(central_widget)# 主布局 - 使用網格布局更靈活main_layout = QGridLayout(central_widget)main_layout.setSpacing(15)main_layout.setContentsMargins(15, 15, 15, 15)# 標題區域title_label = QLabel("郵件客戶端")title_label.setFont(QFont("Arial", 18, QFont.Bold))title_label.setStyleSheet("color: #2c3e50;")main_layout.addWidget(title_label, 0, 0, 1, 3, alignment=Qt.AlignLeft)# 發件人信息main_layout.addWidget(QLabel("發件人:"), 1, 0, alignment=Qt.AlignRight)self.sender_email = QLineEdit()self.sender_email.setPlaceholderText("your_email@qq.com")main_layout.addWidget(self.sender_email, 1, 1, 1, 2)main_layout.addWidget(QLabel("密碼:"), 1, 3, alignment=Qt.AlignRight)self.password = QLineEdit()self.password.setEchoMode(QLineEdit.Password)self.password.setPlaceholderText("郵箱密碼或應用密碼")main_layout.addWidget(self.password, 1, 4)# 收件人 - 標簽和輸入框在同一行main_layout.addWidget(QLabel("收件人:"), 2, 0, alignment=Qt.AlignRight)self.recipient_email = QLineEdit()self.recipient_email.setPlaceholderText("recipient@qq.com")main_layout.addWidget(self.recipient_email, 2, 1, 1, 4)# 主題 - 標簽和輸入框在同一行main_layout.addWidget(QLabel("主題:"), 3, 0, alignment=Qt.AlignRight)self.subject = QLineEdit()self.subject.setPlaceholderText("郵件主題")main_layout.addWidget(self.subject, 3, 1, 1, 4)# 附件main_layout.addWidget(QLabel("附件:"), 4, 0, alignment=Qt.AlignRight | Qt.AlignTop)# 附件列表和按鈕attachment_widget = QWidget()attachment_layout = QVBoxLayout(attachment_widget)self.attachment_list = QListWidget()self.attachment_list.setMinimumHeight(80)attachment_layout.addWidget(self.attachment_list)# 按鈕布局btn_layout = QHBoxLayout()attach_button = QPushButton("添加附件")attach_button.setObjectName("attachButton")attach_button.clicked.connect(self.add_attachment)btn_layout.addWidget(attach_button)remove_button = QPushButton("移除附件")remove_button.setObjectName("attachButton")remove_button.clicked.connect(self.remove_attachment)btn_layout.addWidget(remove_button)attachment_layout.addLayout(btn_layout)main_layout.addWidget(attachment_widget, 4, 1, 1, 4)# 郵件正文 - 擴大區域main_layout.addWidget(QLabel("正文:"), 5, 0, alignment=Qt.AlignRight | Qt.AlignTop)self.body = QTextEdit()self.body.setPlaceholderText("在此輸入郵件內容...")# 設置正文區域的行數(相對擴大)main_layout.addWidget(self.body, 5, 1, 1, 4)# 發送按鈕send_button = QPushButton("發送郵件")send_button.setObjectName("sendButton")send_button.clicked.connect(self.send_email)main_layout.addWidget(send_button, 6, 4, alignment=Qt.AlignRight)# 設置行和列的比例,使正文區域擴大main_layout.setRowStretch(5, 3)  # 正文區域行權重設為3main_layout.setColumnStretch(1, 1)main_layout.setColumnStretch(2, 1)main_layout.setColumnStretch(3, 1)main_layout.setColumnStretch(4, 2)  # 右側列權重更大# 狀態欄self.status_bar = QStatusBar()self.setStatusBar(self.status_bar)self.status_bar.showMessage(f"就緒 - 窗口大小: {self.width()}x{self.height()}")# 存儲附件路徑self.attachments = []# 設置示例數據self.sender_email.setText("your_email@qq.com")self.recipient_email.setText("recipient@qq.com")self.subject.setText("PyQt5 郵件客戶端測試")self.body.setPlainText("這是一封測試郵件,使用 PyQt5 郵件客戶端發送。\n\n""此郵件支持添加多個附件,并采用現代化的界面設計。\n\n""功能包括:\n""? 郵件編寫\n""? 附件添加/移除\n""? 郵件發送\n""? 狀態反饋\n\n""祝您使用愉快!")def add_attachment(self):files, _ = QFileDialog.getOpenFileNames(self, "選擇附件", "", "所有文件 (*.*)")if files:self.attachments.extend(files)self.attachment_list.addItems(files)self.status_bar.showMessage(f"已添加 {len(files)} 個附件")def remove_attachment(self):current_row = self.attachment_list.currentRow()if current_row >= 0:item = self.attachment_list.takeItem(current_row)del self.attachments[current_row]self.status_bar.showMessage(f"已移除附件: {item.text()}")else:self.status_bar.showMessage("請選擇要移除的附件")def send_email(self):sender = self.sender_email.text()password = self.password.text()recipient = self.recipient_email.text()subject = self.subject.text()body = self.body.toPlainText()  # 使用純文本格式if not sender or not password or not recipient:QMessageBox.warning(self, "輸入錯誤", "請填寫完整的發件人、密碼和收件人信息")returntry:# 創建郵件對象msg = MIMEMultipart()msg['From'] = sendermsg['To'] = recipientmsg['Subject'] = subject# 添加郵件正文msg.attach(MIMEText(body, 'plain'))# 添加附件for file_path in self.attachments:try:with open(file_path, "rb") as attachment:part = MIMEBase("application", "octet-stream")part.set_payload(attachment.read())encoders.encode_base64(part)# 獲取文件名filename = file_path.split('/')[-1] if '/' in file_path else file_pathfilename = filename.split('\\')[-1]  # 處理Windows路徑part.add_header("Content-Disposition",f"attachment; filename={filename}",)msg.attach(part)except Exception as e:self.status_bar.showMessage(f"添加附件失敗: {str(e)}")return# 連接SMTP服務器并發送郵件self.status_bar.showMessage("正在連接服務器...")server = smtplib.SMTP_SSL('smtp.gmail.com', 465)  # 使用Gmail SMTP服務器self.status_bar.showMessage("正在登錄...")server.login(sender, password)self.status_bar.showMessage("正在發送郵件...")server.sendmail(sender, recipient, msg.as_string())server.quit()# 發送成功后的操作self.status_bar.showMessage("郵件發送成功!")QMessageBox.information(self, "發送成功", "郵件已成功發送!")# 清空附件列表self.attachment_list.clear()self.attachments = []except smtplib.SMTPAuthenticationError:QMessageBox.critical(self, "認證失敗", "郵箱或密碼錯誤,請檢查您的登錄信息")self.status_bar.showMessage("認證失敗")except Exception as e:QMessageBox.critical(self, "發送失敗", f"郵件發送失敗: {str(e)}")self.status_bar.showMessage(f"發送失敗: {str(e)}")def resizeEvent(self, event):"""窗口大小改變時更新狀態欄信息"""self.status_bar.showMessage(f"就緒 - 窗口大小: {self.width()}x{self.height()}")super().resizeEvent(event)if __name__ == "__main__":app = QApplication(sys.argv)# 設置應用樣式palette = QPalette()palette.setColor(QPalette.Window, QColor(240, 242, 245))palette.setColor(QPalette.WindowText, QColor(51, 51, 51))palette.setColor(QPalette.Base, QColor(255, 255, 255))palette.setColor(QPalette.AlternateBase, QColor(248, 249, 250))palette.setColor(QPalette.Button, QColor(74, 144, 226))palette.setColor(QPalette.ButtonText, QColor(255, 255, 255))palette.setColor(QPalette.Highlight, QColor(74, 144, 226))palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))app.setPalette(palette)client = EmailClient()client.show()sys.exit(app.exec_())

功能說明

這個郵件客戶端實現了以下核心功能:

  1. 郵件編寫

    • 發件人郵箱和密碼輸入
    • 收件人地址輸入
    • 郵件主題輸入
    • 郵件正文編輯區域
  2. 附件管理

    • 添加多個附件
    • 查看附件列表
    • 移除選中的附件
  3. 郵件發送

    • 使用SMTP協議發送郵件
    • 支持純文本格式的郵件內容
    • 支持發送多個附件
    • 錯誤處理和狀態反饋

使用說明

  1. 在"發件人"字段輸入您的郵箱地址
  2. 在"密碼"字段輸入您的郵箱密碼(或應用專用密碼)
  3. 在"收件人"字段輸入收件人郵箱地址
  4. 填寫郵件主題和正文內容
  5. 點擊"添加附件"按鈕選擇要發送的文件
  6. 點擊"發送郵件"按鈕發送郵件

注意事項

  1. 該程序默認使用Gmail的SMTP服務器(smtp.gmail.com:465),如果您使用其他郵箱服務:

    • QQ郵箱:smtp.qq.com:465
    • 163郵箱:smtp.163.com:465
    • Outlook:smtp.office365.com:587(需要使用TLS)
  2. 部分郵箱服務需要開啟SMTP服務并獲取授權碼:

    • Gmail:需要在賬戶設置中開啟"安全性較低的應用的訪問權限"
    • QQ/163:需要在郵箱設置中開啟SMTP服務并獲取授權碼
  3. 出于安全考慮,程序不會保存您的密碼,每次發送郵件都需要輸入

這個程序提供了一個簡潔高效的郵件發送解決方案,代碼結構清晰,去除了不必要的裝飾元素,專注于核心功能的實現。

eMailClient_qt


PyQt5 郵件客戶端 - 優化布局

下面是一個優化布局的郵件客戶端實現,窗口大小調整為1000x600,提供更舒適的編輯體驗:
編寫 eMailClient_qt5.py 如下

import sys
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,QLineEdit, QTextEdit, QPushButton, QLabel, QFileDialog,QListWidget, QMessageBox, QStatusBar, QSplitter, QFrame)
from PyQt5.QtGui import QFont, QPalette, QColor
from PyQt5.QtCore import Qtclass EmailClient(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("郵件客戶端")# 設置窗口大小為1000x600self.setGeometry(100, 100, 1000, 600)# 設置現代化UI樣式self.setStyleSheet("""QMainWindow {background-color: #f0f2f5;}QLabel {color: #333;font-size: 12px;font-weight: bold;padding: 2px 0;}QLineEdit, QTextEdit {background-color: white;border: 1px solid #dcdfe6;border-radius: 4px;padding: 8px;font-size: 13px;}QLineEdit:focus, QTextEdit:focus {border: 1px solid #4a90e2;}QPushButton {background-color: #4a90e2;color: white;border: none;border-radius: 4px;padding: 8px 15px;font-size: 13px;min-height: 30px;}QPushButton:hover {background-color: #3a7bc8;}QPushButton:pressed {background-color: #2a65a8;}QPushButton#attachButton {background-color: #f5f7fa;color: #4a90e2;border: 1px solid #4a90e2;}QPushButton#sendButton {background-color: #27ae60;padding: 10px 25px;font-size: 14px;font-weight: bold;}QPushButton#sendButton:hover {background-color: #219653;}QListWidget {background-color: white;border: 1px solid #dcdfe6;border-radius: 4px;padding: 5px;font-size: 12px;alternate-background-color: #f8f9fa;}QStatusBar {background-color: #e0e6ed;color: #666;font-size: 11px;padding: 5px;}QFrame#headerFrame {background-color: #4a90e2;border-radius: 5px;padding: 10px;}""")# 創建中央部件central_widget = QWidget()self.setCentralWidget(central_widget)# 主布局main_layout = QVBoxLayout(central_widget)main_layout.setSpacing(15)main_layout.setContentsMargins(15, 15, 15, 15)# 標題區域header_frame = QFrame()header_frame.setObjectName("headerFrame")header_layout = QHBoxLayout(header_frame)header_layout.setContentsMargins(10, 5, 10, 5)title_label = QLabel("郵件客戶端")title_label.setFont(QFont("Arial", 18, QFont.Bold))title_label.setStyleSheet("color: white;")header_layout.addWidget(title_label)header_layout.addStretch()main_layout.addWidget(header_frame)# 創建分割器,左側為設置區域,右側為編輯區域splitter = QSplitter(Qt.Horizontal)main_layout.addWidget(splitter, 1)# 左側設置面板settings_panel = QWidget()settings_layout = QVBoxLayout(settings_panel)settings_layout.setContentsMargins(0, 0, 10, 0)# 發件人信息sender_group = QWidget()sender_layout = QVBoxLayout(sender_group)sender_layout.addWidget(QLabel("發件人設置"))sender_form = QHBoxLayout()sender_form.addWidget(QLabel("郵箱:"))self.sender_email = QLineEdit()self.sender_email.setPlaceholderText("your_email@example.com")sender_form.addWidget(self.sender_email)sender_layout.addLayout(sender_form)sender_form2 = QHBoxLayout()sender_form2.addWidget(QLabel("密碼:"))self.password = QLineEdit()self.password.setEchoMode(QLineEdit.Password)self.password.setPlaceholderText("郵箱密碼或應用密碼")sender_form2.addWidget(self.password)sender_layout.addLayout(sender_form2)settings_layout.addWidget(sender_group)# 收件人recipient_group = QWidget()recipient_layout = QVBoxLayout(recipient_group)recipient_layout.addWidget(QLabel("收件人"))self.recipient_email = QLineEdit()self.recipient_email.setPlaceholderText("recipient@example.com")recipient_layout.addWidget(self.recipient_email)settings_layout.addWidget(recipient_group)# 主題subject_group = QWidget()subject_layout = QVBoxLayout(subject_group)subject_layout.addWidget(QLabel("主題"))self.subject = QLineEdit()self.subject.setPlaceholderText("郵件主題")subject_layout.addWidget(self.subject)settings_layout.addWidget(subject_group)# 附件attachment_group = QWidget()attachment_layout = QVBoxLayout(attachment_group)attachment_layout.addWidget(QLabel("附件"))# 附件列表self.attachment_list = QListWidget()self.attachment_list.setMinimumHeight(100)attachment_layout.addWidget(self.attachment_list)# 附件按鈕btn_layout = QHBoxLayout()attach_button = QPushButton("添加附件")attach_button.setObjectName("attachButton")attach_button.clicked.connect(self.add_attachment)btn_layout.addWidget(attach_button)remove_button = QPushButton("移除附件")remove_button.setObjectName("attachButton")remove_button.clicked.connect(self.remove_attachment)btn_layout.addWidget(remove_button)attachment_layout.addLayout(btn_layout)settings_layout.addWidget(attachment_group)settings_layout.addStretch()# 右側編輯區域editor_panel = QWidget()editor_layout = QVBoxLayout(editor_panel)editor_layout.setContentsMargins(0, 0, 0, 0)# 郵件正文editor_layout.addWidget(QLabel("郵件正文"))self.body = QTextEdit()self.body.setPlaceholderText("在此輸入郵件內容...")editor_layout.addWidget(self.body, 1)# 發送按鈕send_button = QPushButton("發送郵件")send_button.setObjectName("sendButton")send_button.clicked.connect(self.send_email)editor_layout.addWidget(send_button, 0, Qt.AlignRight)# 添加左右面板到分割器splitter.addWidget(settings_panel)splitter.addWidget(editor_panel)splitter.setSizes([300, 700])# 狀態欄self.status_bar = QStatusBar()self.setStatusBar(self.status_bar)self.status_bar.showMessage("就緒 - 窗口大小: 1000x600")# 存儲附件路徑self.attachments = []# 設置示例數據self.sender_email.setText("your_email@example.com")self.recipient_email.setText("recipient@example.com")self.subject.setText("PyQt5 郵件客戶端測試")self.body.setPlainText("這是一封測試郵件,使用 PyQt5 郵件客戶端發送。\n\n""此郵件支持添加多個附件,并采用現代化的界面設計。\n\n""功能包括:\n""? 郵件編寫\n""? 附件添加/移除\n""? 郵件發送\n""? 狀態反饋\n\n""祝您使用愉快!")def add_attachment(self):files, _ = QFileDialog.getOpenFileNames(self, "選擇附件", "", "所有文件 (*.*)")if files:self.attachments.extend(files)self.attachment_list.addItems(files)self.status_bar.showMessage(f"已添加 {len(files)} 個附件")def remove_attachment(self):current_row = self.attachment_list.currentRow()if current_row >= 0:item = self.attachment_list.takeItem(current_row)del self.attachments[current_row]self.status_bar.showMessage(f"已移除附件: {item.text()}")else:self.status_bar.showMessage("請選擇要移除的附件")def send_email(self):sender = self.sender_email.text()password = self.password.text()recipient = self.recipient_email.text()subject = self.subject.text()body = self.body.toPlainText()  # 使用純文本格式if not sender or not password or not recipient:QMessageBox.warning(self, "輸入錯誤", "請填寫完整的發件人、密碼和收件人信息")returntry:# 創建郵件對象msg = MIMEMultipart()msg['From'] = sendermsg['To'] = recipientmsg['Subject'] = subject# 添加郵件正文msg.attach(MIMEText(body, 'plain'))# 添加附件for file_path in self.attachments:try:with open(file_path, "rb") as attachment:part = MIMEBase("application", "octet-stream")part.set_payload(attachment.read())encoders.encode_base64(part)# 獲取文件名filename = file_path.split('/')[-1] if '/' in file_path else file_pathfilename = filename.split('\\')[-1]  # 處理Windows路徑part.add_header("Content-Disposition",f"attachment; filename={filename}",)msg.attach(part)except Exception as e:self.status_bar.showMessage(f"添加附件失敗: {str(e)}")return# 連接SMTP服務器并發送郵件self.status_bar.showMessage("正在連接服務器...")server = smtplib.SMTP_SSL('smtp.gmail.com', 465)  # 使用Gmail SMTP服務器self.status_bar.showMessage("正在登錄...")server.login(sender, password)self.status_bar.showMessage("正在發送郵件...")server.sendmail(sender, recipient, msg.as_string())server.quit()# 發送成功后的操作self.status_bar.showMessage("郵件發送成功!")QMessageBox.information(self, "發送成功", "郵件已成功發送!")# 清空附件列表self.attachment_list.clear()self.attachments = []except smtplib.SMTPAuthenticationError:QMessageBox.critical(self, "認證失敗", "郵箱或密碼錯誤,請檢查您的登錄信息")self.status_bar.showMessage("認證失敗")except Exception as e:QMessageBox.critical(self, "發送失敗", f"郵件發送失敗: {str(e)}")self.status_bar.showMessage(f"發送失敗: {str(e)}")if __name__ == "__main__":app = QApplication(sys.argv)# 設置應用樣式palette = QPalette()palette.setColor(QPalette.Window, QColor(240, 242, 245))palette.setColor(QPalette.WindowText, QColor(51, 51, 51))palette.setColor(QPalette.Base, QColor(255, 255, 255))palette.setColor(QPalette.AlternateBase, QColor(248, 249, 250))palette.setColor(QPalette.Button, QColor(74, 144, 226))palette.setColor(QPalette.ButtonText, QColor(255, 255, 255))palette.setColor(QPalette.Highlight, QColor(74, 144, 226))palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))app.setPalette(palette)client = EmailClient()client.show()sys.exit(app.exec_())

功能說明

這個郵件客戶端具有以下特點:

  1. 現代化UI設計

    • 藍色主題與現代化界面元素
    • 分割布局(左側設置區,右側編輯區)
    • 響應式設計,適應1000x600窗口尺寸
  2. 郵件功能

    • 完整的郵件編寫功能
    • 多附件支持(添加/移除)
    • SMTP郵件發送
  3. 用戶體驗優化

    • 狀態提示(連接、登錄、發送狀態)
    • 詳細的錯誤反饋
    • 清晰的視覺層次結構
  4. 布局優化

    • 左側設置面板:發件人信息、收件人、主題、附件管理
    • 右側編輯面板:郵件正文編輯區域
    • 底部狀態欄:顯示操作狀態和反饋

使用說明

  1. 左側設置面板

    • 輸入發件人郵箱和密碼
    • 輸入收件人郵箱地址
    • 填寫郵件主題
    • 管理附件(添加/移除)
  2. 右側編輯面板

    • 在正文區域編寫郵件內容
    • 點擊"發送郵件"按鈕發送
  3. 狀態反饋

    • 狀態欄顯示當前操作狀態
    • 發送成功/失敗會有彈窗提示

技術特點

  1. 窗口尺寸

    • 主窗口設置為1000x600像素,提供寬敞的編輯空間
    • 使用QSplitter實現可調整大小的面板
  2. 郵件發送

    • 支持Gmail SMTP服務器(可修改為其他服務商)
    • 支持純文本郵件內容
    • 支持多個附件發送
  3. 錯誤處理

    • 詳細的錯誤捕獲和反饋
    • 認證失敗、發送失敗等情況的專門處理

這個郵件客戶端在保持功能完整性的同時,提供了更加現代化和專業的用戶界面,充分利用了1000x600的窗口空間,為用戶帶來更舒適的郵件編輯體驗。

eMailClient_qt5

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/909468.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/909468.shtml
英文地址,請注明出處:http://en.pswp.cn/news/909468.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

React【回顧】 深層次面試詳解:函數式組件核心原理與高級優化

以下是對 React 深層次內容的全面解析,涵蓋函數式組件的核心原理、性能優化、設計模式和最新特性: ?? 一、React 核心機制剖析 1. Fiber 架構深解 Fiber 節點結構:function FiberNode(tag, pendingProps, key) {this.tag = tag; // 組件類型(函數組件=0, 類…

視覺語言模型的“視而不見“

這項研究發現,號稱能“看圖說話”的視覺語言模型(VLMs),在處理需要真正“看”懂圖片的純視覺任務(如判斷深度、找對應點、認物體材質等)時,表現遠不如它們自己內部的“眼睛”(視覺編…

Wyn 商業智能與 3D 大屏的深度融合應用

引言 在當今數字化快速發展的時代,數據可視化對于企業的決策和管理變得至關重要。商業智能軟件作為數據可視化的重要工具,能夠幫助企業將海量的數據轉化為直觀、易懂的信息。而 3D 大屏以其沉浸式、立體的展示效果,為數據可視化帶來了全新的…

使用docker compose部署netmaker打通內網

準備 我看官網推薦都是使用ssl然后要ssl證書,不想走彎路了 一、docker-compose.yml version: "3.4"services:netmaker:container_name: netmakerimage: gravitl/netmaker:v0.90.0restart: unless-stoppedports:- "18081:18082"- "50051…

Linux集市采購指南[特殊字符]:yum和apt的“搶貨”大戰!

Linux集市采購指南🍅:yum和apt的“搶貨”大戰! ? 歡迎來到 Linux軟件生態集市!這里分兩大陣營: 🥬 CentOS/RHEL傳統菜市場:派穩重的 yum 大叔當采購員,做事一板一眼;?…

DataX 框架學習筆記

官方倉庫: https://github.com/alibaba/DataX?tabreadme-ov-file 1. 介紹 1.1. 基本介紹: DadaX 是阿里云 DataWorks 數據集成 的開源版本(異構數據同步、離線數據同步工具 / 平臺)。主要抽象為 Reader 和 Writer 插件&#…

MaxCompute的Logview分析詳解

文章目錄 一、Logview簡介1、概述2、標題與功能3、基礎信息 二、作業詳情1、Job Details2、Fuxi Sensor3、Result①當前作業運行成功,顯示的為運行結果。②當前作業運行失敗,顯示的為失敗原因。 4、SourceXML5、SQL Script6、History7、SubStatusHistory…

HTML5白云飄飄動態效果教程

HTML5白云飄飄動態效果教程 這里寫目錄標題 HTML5白云飄飄動態效果教程效果介紹實現步驟步驟一:創建HTML結構步驟二:設計CSS樣式步驟三:添加JavaScript交互 代碼解析HTML結構解析CSS樣式解析JavaScript功能解析 自定義調整總結 效果介紹 本教…

tcp高難度問題

以下是針對這些問題,在面試場景下,既保證理論扎實、邏輯清晰,又具備交流延展性的回答思路與內容,可根據實際面試節奏和面試官反饋靈活調整展開: 1. 客戶端端口號如何確定的? 面試官您好,客戶端…

廣東省省考備考(第二十八天6.13)—資料分析(第二節課)

基期與現期 官方定義:作為對比參照的是基期,而相對于基期比較的是現期 通俗說法:時間靠前的為基期,時間靠后的為現期 增長量與增長率 增長量用來表述基期量與現期量變化的絕對量; 增長率用來表述基期量與現期量變化…

pytorch 中前向傳播和后向傳播的自定義函數

系列文章目錄 文章目錄 系列文章目錄一、torch.autograd.function代碼實例 在開始正文之前,請各位姥爺動動手指,給小店增加一點訪問量吧,點擊小店,同時希望我的文章對你的學習有所幫助。本文也很簡單,主要講解pytorch的…

【項目實訓#08】HarmonyOS知識圖譜前端可視化實現

【項目實訓#08】HarmonyOS知識圖譜前端可視化實現 文章目錄 【項目實訓#08】HarmonyOS知識圖譜前端可視化實現一、背景簡介二、技術方案與架構設計2.1 技術選型2.2 組件架構設計 三、知識圖譜可視化組件實現3.1 KGResultTab組件設計組件模板結構不同狀態的處理用戶交互控制節點…

【軟件開發】什么是DSL

什么是DSL DSL(Domain-Specific Language,領域特定語言)是一種為特定領域或任務設計的編程語言,目的在于提高該領域中的表達能力與開發效率。 1 在腳本語言中的 DSL 是什么? 在腳本語言(如 Python、Lua、…

JasperReport生成PDF/A類型文檔

當JasperReport導出的文檔為PDF/A模式時,該PDF為只讀可以防止被修改。 設置導出參數 JRPdfExporter exporter new JRPdfExporter();exporter.setExporterInput(SimpleExporterInput.getInstance(jasperPrints));exporter.setExporterOutput(new SimpleOutputStre…

微信小程序使用畫布實現飄落泡泡功能

微信小程序使用畫布實現飄落泡泡功能:從組件封裝到頁面調用的完整實踐 先看示例截圖: 一、背景與技術選型 在微信小程序中實現類似于飄落的泡泡或者櫻花飄落的功能,一般主要有 Canvas 和圖片兩種方案: (1&#xff…

使用STM32設置GPIO中斷

使用S? 32設置GPIO中斷 中斷示例按鍵中斷實例設計:EXTI0和EXTI9硬件連接分析STM32代碼實現代碼說明 中斷示例 設計一個按鍵中斷的實例。設置兩個中斷:EXTI0、EXTI9, 在EXTI9的中斷服務之程序中實現LED燈的控制 按鍵中斷實例設計&#xff…

解決在微信小程序中view組件下的text和images設置了樣式display: flex; align-items: center;對不齊

原始代碼的問題 <view style"display: flex; align-items: center;"><text style"line-height: 1;">全國</text><image src"/images/xia.png" style"height: 20rpx; width: 20rpx; display: block;"></im…

歸并排序詳解:優雅的分治藝術

什么&#xff1f;歸并排序&#xff1f;這讓博主想起了大學那會被《數據結構與算法》支配的恐懼… 哈哈言歸正傳&#xff0c;一直想對算法做一個專欄&#xff0c;因為其實工作中很少很少有機會用到算法&#xff0c;倒是很多工具方法底層會使用&#xff0c;工作被各種需求業務“折…

新零售視域下實體與虛擬店融合的技術邏輯與商業模式創新——基于開源AI智能名片與鏈動2+1模式的S2B2C生態構建

摘要&#xff1a;新零售的核心在于打破線上線下邊界&#xff0c;構建“人、貨、場”的全場景融合生態。本文提出&#xff0c;實體線下店與虛擬店的協同發展是新零售的重要演進方向&#xff0c;其底層邏輯在于滿足消費者作為“現實人”的體驗需求與“虛擬人”的效率需求。通過引…

可視化圖解算法51:尋找第K大(數組中的第K個最大的元素)

牛客網 面試筆試 TOP101 | LeetCode 215. 數組中的第K個最大元素 1. 題目 描述 有一個整數數組&#xff0c;請你找出數組中第 k 大的數。 給定一個整數數組 a ,同時給定它的大小n和要找的 k &#xff0c;請返回第 k 大的數(包括重復的元素&#xff0c;不用去重)&…