亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

使用Python開(kāi)發(fā)一個(gè)現(xiàn)代化屏幕取色器

 更新時(shí)間:2025年06月12日 16:35:17   作者:創(chuàng)客白澤  
在UI設(shè)計(jì)、網(wǎng)頁(yè)開(kāi)發(fā)等場(chǎng)景中,顏色拾取是高頻需求,這篇文章主要介紹了如何使用Python開(kāi)發(fā)一個(gè)現(xiàn)代化屏幕取色器,有需要的小伙伴可以參考一下

一、項(xiàng)目概述

在UI設(shè)計(jì)、網(wǎng)頁(yè)開(kāi)發(fā)等場(chǎng)景中,顏色拾取是高頻需求。本文介紹的Modern Color Picker具有以下特點(diǎn):

  • 現(xiàn)代化UI設(shè)計(jì) - 采用Fluent Design風(fēng)格
  • 高性能取色 - 多線程實(shí)現(xiàn)毫秒級(jí)響應(yīng)
  • 智能反饋 - 可視化顏色預(yù)覽+復(fù)制提示
  • 跨平臺(tái)兼容 - 核心邏輯支持Windows/macOS

二、核心功能解析

2.1 實(shí)時(shí)顏色追蹤

def track_mouse_color(self):
    while not self.stop_thread:
        if self.left_pressed:
            x, y = pyautogui.position()
            rgb = self.get_color_at(x, y)
            self.color_changed.emit(rgb)
        time.sleep(0.03)

獨(dú)立線程處理鼠標(biāo)坐標(biāo)獲取

通過(guò)信號(hào)槽機(jī)制更新UI

33fps的采樣頻率平衡性能與流暢度

2.2 智能顏色顯示

# 根據(jù)亮度自動(dòng)調(diào)整文本顏色
brightness = sqrt(0.299*color.red()**2 + 0.587*color.green()**2 + 0.114*color.blue()**2)
text_color = QColor("#ffffff" if brightness < 128 else "#333333")

使用光度公式實(shí)現(xiàn)智能反色,確保文字始終可見(jiàn)

三、效果展示

四、實(shí)現(xiàn)步驟詳解

4.1 環(huán)境配置

pip install pyqt5 pyautogui pillow pywin32

4.2 關(guān)鍵實(shí)現(xiàn)步驟

創(chuàng)建無(wú)邊框窗口

   self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
   self.setAttribute(Qt.WA_TranslucentBackground)

設(shè)計(jì)顏色預(yù)覽組件

   path.addRoundedRect(0, 0, self.width(), self.height(), 12, 12)
   painter.fillPath(path, QColor(self.color))

實(shí)現(xiàn)拖拽取色邏輯

   def on_mouse_down(self, event):
       self.left_pressed = True
       
   def on_mouse_up(self, event):
       if self.left_pressed:
           x, y = pyautogui.position()
           rgb = self.get_color_at(x, y)

五、代碼深度解析

5.1 架構(gòu)設(shè)計(jì)

5.2 性能優(yōu)化點(diǎn)

  • 雙緩沖繪圖QPainter.setRenderHint(QPainter.Antialiasing)
  • 資源復(fù)用:重復(fù)使用QPixmap緩存
  • 線程安全:通過(guò)信號(hào)槽跨線程通信

六、完整源碼

import sys
import pyautogui
from PIL import ImageGrab
import win32clipboard
import threading
import time
from math import sqrt
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QLabel, QPushButton, QFrame, QSizePolicy)
from PyQt5.QtCore import Qt, QSize, QPoint, QTimer, pyqtSignal
from PyQt5.QtGui import QColor, QPainter, QPainterPath, QFont, QFontDatabase, QPixmap, QIcon

class ModernColorPicker(QMainWindow):
    color_changed = pyqtSignal(tuple)  # 顏色變化信號(hào)

    def __init__(self):
        super().__init__()
        self.setup_ui()
        self.setup_window()
        
        # 初始化變量
        self.left_pressed = False
        self.stop_thread = False
        self.drag_start_pos = QPoint()
        self.current_rgb = None
        self.current_hex = None
        
        # 啟動(dòng)顏色跟蹤線程
        self.track_thread = threading.Thread(target=self.track_mouse_color)
        self.track_thread.daemon = True
        self.track_thread.start()
        
        # 連接信號(hào)
        self.color_changed.connect(self.update_current_color)

    def setup_window(self):
        """設(shè)置窗口屬性"""
        self.setWindowTitle("?? Modern Color Picker")
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        
        # 設(shè)置窗口大小和位置
        screen = QApplication.primaryScreen().geometry()
        self.setFixedSize(400, 550)
        self.move(screen.width() - self.width() - 20, 
                 (screen.height() - self.height()) // 2)
        
        # 窗口陰影效果
        self.shadow = QWidget(self)
        self.shadow.setGeometry(3, 3, self.width(), self.height())
        self.shadow.setStyleSheet("background-color: rgba(0, 0, 0, 50); border-radius: 12px;")
        self.shadow.lower()

    def setup_ui(self):
        """設(shè)置用戶界面"""
        # 主窗口
        main_widget = QWidget()
        main_widget.setObjectName("mainWidget")
        main_widget.setStyleSheet("""
            #mainWidget {
                background-color: #f5f5f7;
                border-radius: 10px;
            }
            QLabel {
                color: #333333;
            }
        """)
        self.setCentralWidget(main_widget)
        
        # 主布局
        main_layout = QVBoxLayout(main_widget)
        main_layout.setContentsMargins(20, 15, 20, 15)
        main_layout.setSpacing(0)
        
        # 標(biāo)題欄
        self.setup_title_bar(main_layout)
        
        # 顏色預(yù)覽區(qū)域
        self.setup_color_previews(main_layout)
        
        # 顏色信息顯示
        self.setup_color_info(main_layout)
        
        # 操作按鈕
        self.setup_action_buttons(main_layout)
        
        # 取色區(qū)域
        self.setup_pick_area(main_layout)
        
        # 狀態(tài)欄
        self.status_label = QLabel("")
        self.status_label.setAlignment(Qt.AlignCenter)
        self.status_label.setStyleSheet("""
            QLabel {
                color: #007AFF;
                font: 9pt "Segoe UI";
                padding: 5px 0;
            }
        """)
        main_layout.addWidget(self.status_label)

    def setup_title_bar(self, parent_layout):
        """設(shè)置自定義標(biāo)題欄"""
        title_bar = QWidget()
        title_bar.setFixedHeight(40)
        title_bar.setStyleSheet("background-color: #2c2c2e; border-radius: 10px 10px 0 0;")
        
        # 標(biāo)題欄布局
        title_layout = QHBoxLayout(title_bar)
        title_layout.setContentsMargins(15, 0, 15, 0)
        title_layout.setSpacing(0)
        
        # 標(biāo)題
        title_label = QLabel("?? Modern Color Picker")
        title_label.setStyleSheet("""
            QLabel {
                color: white;
                font: bold 10pt "Segoe UI";
            }
        """)
        
        # 按鈕區(qū)域
        btn_widget = QWidget()
        btn_layout = QHBoxLayout(btn_widget)
        btn_layout.setContentsMargins(0, 0, 0, 0)
        btn_layout.setSpacing(10)
        
        # 最小化按鈕
        minimize_btn = QPushButton("-")
        minimize_btn.setFixedSize(20, 20)
        minimize_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: white;
                font: 12pt "Segoe UI";
                border: none;
            }
            QPushButton:hover {
                background-color: #3a3a3c;
                border-radius: 10px;
            }
        """)
        minimize_btn.clicked.connect(self.showMinimized)
        
        # 關(guān)閉按鈕
        close_btn = QPushButton("×")
        close_btn.setFixedSize(20, 20)
        close_btn.setStyleSheet("""
            QPushButton {
                background-color: transparent;
                color: white;
                font: 12pt "Segoe UI";
                border: none;
            }
            QPushButton:hover {
                background-color: #ff5f56;
                border-radius: 10px;
            }
        """)
        close_btn.clicked.connect(self.exit_app)
        
        # 添加到布局
        btn_layout.addWidget(minimize_btn)
        btn_layout.addWidget(close_btn)
        
        title_layout.addWidget(title_label, 0, Qt.AlignLeft)
        title_layout.addStretch()
        title_layout.addWidget(btn_widget, 0, Qt.AlignRight)
        
        parent_layout.addWidget(title_bar)

    def setup_color_previews(self, parent_layout):
        """設(shè)置顏色預(yù)覽區(qū)域"""
        preview_widget = QWidget()
        preview_layout = QHBoxLayout(preview_widget)
        preview_layout.setContentsMargins(0, 10, 0, 20)
        preview_layout.setSpacing(40)
        
        # 當(dāng)前顏色預(yù)覽
        current_frame = QVBoxLayout()
        current_frame.setSpacing(8)
        
        current_label = QLabel("?? 當(dāng)前顏色")
        current_label.setStyleSheet("""
            QLabel {
                font: bold 10pt "Segoe UI";
                color: #333333;
            }
        """)
        current_label.setAlignment(Qt.AlignCenter)
        
        self.current_color_preview = ColorPreviewWidget()
        self.current_color_preview.setFixedSize(80, 80)
        
        current_frame.addWidget(current_label)
        current_frame.addWidget(self.current_color_preview, 0, Qt.AlignCenter)
        
        # 確認(rèn)顏色預(yù)覽
        confirm_frame = QVBoxLayout()
        confirm_frame.setSpacing(8)
        
        confirm_label = QLabel("? 確認(rèn)顏色")
        confirm_label.setStyleSheet("""
            QLabel {
                font: bold 10pt "Segoe UI";
                color: #333333;
            }
        """)
        confirm_label.setAlignment(Qt.AlignCenter)
        
        self.confirm_color_preview = ColorPreviewWidget()
        self.confirm_color_preview.setFixedSize(80, 80)
        
        confirm_frame.addWidget(confirm_label)
        confirm_frame.addWidget(self.confirm_color_preview, 0, Qt.AlignCenter)
        
        # 添加到布局
        preview_layout.addLayout(current_frame)
        preview_layout.addLayout(confirm_frame)
        
        parent_layout.addWidget(preview_widget)

    def setup_color_info(self, parent_layout):
        """設(shè)置顏色信息顯示區(qū)域"""
        # 創(chuàng)建一個(gè)垂直布局容器來(lái)包裹兩個(gè)信息框
        color_info_container = QVBoxLayout()
        color_info_container.setContentsMargins(0, 0, 0, 0)
        color_info_container.setSpacing(10)  # 這里設(shè)置兩個(gè)信息框之間的間距
        
        # RGB值顯示
        self.rgb_frame = InfoFrame("?? RGB:")
        self.rgb_value = QLabel("")
        self.rgb_value.setStyleSheet("""
            QLabel {
                font: bold 10pt "Segoe UI";
                color: #333333;
            }
        """)
        self.rgb_frame.add_info_widget(self.rgb_value)
        
        # HEX值顯示
        self.hex_frame = InfoFrame("?? HEX:")
        self.hex_value = QLabel("")
        self.hex_value.setStyleSheet("""
            QLabel {
                font: bold 10pt "Segoe UI";
                color: #333333;
            }
        """)
        self.hex_frame.add_info_widget(self.hex_value)
        
        # 添加到容器布局
        color_info_container.addWidget(self.rgb_frame)
        color_info_container.addWidget(self.hex_frame)
        
        # 將容器布局添加到父布局
        parent_layout.addLayout(color_info_container)

    def setup_action_buttons(self, parent_layout):
        """設(shè)置操作按鈕"""
        btn_widget = QWidget()
        btn_layout = QHBoxLayout(btn_widget)
        btn_layout.setContentsMargins(0, 10, 0, 20)
        btn_layout.setSpacing(10)
        
        # 復(fù)制RGB按鈕
        self.copy_rgb_btn = ModernButton("?? 復(fù)制 RGB")
        self.copy_rgb_btn.setEnabled(False)
        self.copy_rgb_btn.clicked.connect(self.copy_rgb)
        
        # 復(fù)制HEX按鈕
        self.copy_hex_btn = ModernButton("?? 復(fù)制 HEX")
        self.copy_hex_btn.setEnabled(False)
        self.copy_hex_btn.clicked.connect(self.copy_hex)
        
        # 添加到布局
        btn_layout.addWidget(self.copy_rgb_btn)
        btn_layout.addWidget(self.copy_hex_btn)
        
        parent_layout.addWidget(btn_widget)

    def setup_pick_area(self, parent_layout):
        """設(shè)置取色區(qū)域"""
        self.pick_area = QLabel("??? 按住鼠標(biāo)右鍵不放\n\n?? 拖動(dòng)到目標(biāo)位置\n\n? 松開(kāi)以確認(rèn)顏色")
        self.pick_area.setAlignment(Qt.AlignCenter)
        self.pick_area.setStyleSheet("""
            QLabel {
                background-color: #ffffff;
                border: 1px solid #e0e0e0;
                border-radius: 8px;
                font: 11pt "Segoe UI";
                color: #666666;
                padding: 20px;
            }
        """)
        self.pick_area.setCursor(Qt.CrossCursor)
        
        # 鼠標(biāo)事件
        self.pick_area.mousePressEvent = self.on_mouse_down
        self.pick_area.mouseReleaseEvent = self.on_mouse_up
        
        parent_layout.addWidget(self.pick_area)

    # ========== 事件處理 ==========
    def mousePressEvent(self, event):
        """鼠標(biāo)按下事件(用于窗口拖動(dòng))"""
        if event.button() == Qt.LeftButton:
            self.drag_start_pos = event.globalPos() - self.pos()
            event.accept()

    def mouseMoveEvent(self, event):
        """鼠標(biāo)移動(dòng)事件(用于窗口拖動(dòng))"""
        if event.buttons() == Qt.LeftButton:
            self.move(event.globalPos() - self.drag_start_pos)
            self.shadow.move(self.pos() + QPoint(3, 3))
            event.accept()

    def on_mouse_down(self, event):
        """取色區(qū)域鼠標(biāo)按下事件"""
        self.left_pressed = True
        self.rgb_value.setText("")
        self.hex_value.setText("")
        self.confirm_color_preview.set_color("#ffffff")
        self.copy_rgb_btn.setEnabled(False)
        self.copy_hex_btn.setEnabled(False)
        self.pick_area.setText("?? 拖動(dòng)到目標(biāo)位置\n\n? 松開(kāi)以確認(rèn)顏色")

    def on_mouse_up(self, event):
        """取色區(qū)域鼠標(biāo)釋放事件"""
        if self.left_pressed:
            self.left_pressed = False
            x, y = pyautogui.position()
            rgb = self.get_color_at(x, y)
            hex_color = '#%02x%02x%02x' % rgb

            # 更新UI
            self.rgb_value.setText(f"{rgb[0]}, {rgb[1]}, {rgb[2]}")
            self.hex_value.setText(hex_color.upper())
            self.copy_rgb_btn.setEnabled(True)
            self.copy_hex_btn.setEnabled(True)
            
            # 保存當(dāng)前顏色
            self.current_rgb = f"{rgb[0]}, {rgb[1]}, {rgb[2]}"
            self.current_hex = hex_color.upper()
            
            # 更新確認(rèn)顏色預(yù)覽
            self.confirm_color_preview.set_color(hex_color)
            
            # 自動(dòng)復(fù)制HEX到剪貼板
            self.copy_to_clipboard(hex_color.upper())
            self.show_status(f"?? 顏色 {hex_color.upper()} 已復(fù)制到剪貼板", 3000)
            
            # 恢復(fù)取色區(qū)域提示
            self.pick_area.setText("??? 按住鼠標(biāo)左鍵不放\n\n?? 拖動(dòng)到目標(biāo)位置\n\n? 松開(kāi)以確認(rèn)顏色")

    # ========== 功能方法 ==========
    def get_color_at(self, x, y):
        """獲取指定位置的顏色"""
        img = ImageGrab.grab(bbox=(x, y, x + 1, y + 1))
        return img.getpixel((0, 0))

    def copy_to_clipboard(self, text):
        """復(fù)制文本到剪貼板"""
        win32clipboard.OpenClipboard()
        win32clipboard.EmptyClipboard()
        win32clipboard.SetClipboardText(text)
        win32clipboard.CloseClipboard()

    def update_current_color(self, rgb):
        """更新當(dāng)前顏色預(yù)覽"""
        hex_color = '#%02x%02x%02x' % rgb
        self.current_color_preview.set_color(hex_color)

    def track_mouse_color(self):
        """跟蹤鼠標(biāo)位置的顏色"""
        while not self.stop_thread:
            if self.left_pressed:
                x, y = pyautogui.position()
                rgb = self.get_color_at(x, y)
                self.color_changed.emit(rgb)
            time.sleep(0.03)

    def copy_rgb(self):
        """復(fù)制RGB值"""
        if self.current_rgb:
            self.copy_to_clipboard(self.current_rgb)
            self.flash_button(self.copy_rgb_btn, "? 已復(fù)制")

    def copy_hex(self):
        """復(fù)制HEX值"""
        if self.current_hex:
            self.copy_to_clipboard(self.current_hex)
            self.flash_button(self.copy_hex_btn, "? 已復(fù)制")

    def flash_button(self, button, temp_text):
        """按鈕點(diǎn)擊反饋效果"""
        original_text = button.text()
        button.setText(temp_text)
        button.setStyleSheet("""
            QPushButton {
                background-color: #34C759;
                color: white;
                font: bold 10pt "Segoe UI";
                border-radius: 6px;
                padding: 8px 20px;
            }
        """)
        
        QTimer.singleShot(1500, lambda: (
            button.setText(original_text),
            button.setStyleSheet("""
                QPushButton {
                    background-color: #007AFF;
                    color: white;
                    font: bold 10pt "Segoe UI";
                    border-radius: 6px;
                    padding: 8px 20px;
                }
                QPushButton:hover {
                    background-color: #0062CC;
                }
                QPushButton:disabled {
                    background-color: #AEAEB2;
                }
            """)
        ))

    def show_status(self, message, duration):
        """顯示狀態(tài)消息"""
        self.status_label.setText(message)
        QTimer.singleShot(duration, lambda: self.status_label.setText(""))

    def exit_app(self):
        """退出應(yīng)用程序"""
        self.stop_thread = True
        self.close()

# ========== 自定義控件 ==========
class ColorPreviewWidget(QWidget):
    """顏色預(yù)覽控件"""
    def __init__(self, parent=None):
        super().__init__(parent)
        self.color = "#ffffff"
        self.setMinimumSize(80, 80)

    def set_color(self, color):
        """設(shè)置顏色"""
        self.color = color
        self.update()

    def paintEvent(self, event):
        """繪制圓角顏色預(yù)覽"""
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)
        
        # 繪制圓角矩形
        path = QPainterPath()
        path.addRoundedRect(0, 0, self.width(), self.height(), 12, 12)
        
        # 填充顏色
        painter.fillPath(path, QColor(self.color))
        
        # 繪制邊框
        painter.setPen(QColor("#e0e0e0"))
        painter.drawPath(path)
        
        # 根據(jù)亮度決定文字顏色
        color = QColor(self.color)
        brightness = sqrt(0.299 * color.red()**2 + 0.587 * color.green()**2 + 0.114 * color.blue()**2)
        text_color = QColor("#ffffff" if brightness < 128 else "#333333")
        
        # 在中心繪制HEX值
        painter.setPen(text_color)
        painter.setFont(QFont("Segoe UI", 9))
        painter.drawText(self.rect(), Qt.AlignCenter, self.color.upper())

class InfoFrame(QFrame):
    """信息顯示框"""
    def __init__(self, title, parent=None):
        super().__init__(parent)
        self.setFrameShape(QFrame.NoFrame)
        self.setStyleSheet("""
            QFrame {
                background-color: #ffffff;
                border-radius: 8px;
            }
        """)
        self.setFixedHeight(40)
        
        # 布局
        layout = QHBoxLayout(self)
        layout.setContentsMargins(15, 10, 15, 10)
        layout.setSpacing(5)
        
        # 標(biāo)題
        title_label = QLabel(title)
        title_label.setStyleSheet("""
            QLabel {
                font: 10pt "Segoe UI";
                color: #666666;
            }
        """)
        layout.addWidget(title_label)
        
        # 信息區(qū)域
        self.info_widget = QWidget()
        self.info_layout = QHBoxLayout(self.info_widget)
        self.info_layout.setContentsMargins(0, 0, 0, 0)
        self.info_layout.setSpacing(0)
        
        layout.addWidget(self.info_widget)
        layout.addStretch()

    def add_info_widget(self, widget):
        """添加信息控件"""
        self.info_layout.addWidget(widget)

class ModernButton(QPushButton):
    """現(xiàn)代化按鈕"""
    def __init__(self, text, parent=None):
        super().__init__(text, parent)
        self.setCursor(Qt.PointingHandCursor)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self.setStyleSheet("""
            QPushButton {
                background-color: #007AFF;
                color: white;
                font: bold 10pt "Segoe UI";
                border-radius: 6px;
                padding: 8px 20px;
            }
            QPushButton:hover {
                background-color: #0062CC;
            }
            QPushButton:disabled {
                background-color: #AEAEB2;
            }
        """)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 設(shè)置應(yīng)用程序字體
    font_db = QFontDatabase()
    if "Segoe UI" in font_db.families():
        app.setFont(QFont("Segoe UI", 9))
    else:
        app.setFont(QFont("Arial", 9))
    
    window = ModernColorPicker()
    window.show()
    sys.exit(app.exec_())

關(guān)鍵文件結(jié)構(gòu):

/ModernColorPicker
│── main.py            # 程序入口
│── components.py      # 自定義組件
│── requirements.txt   # 依賴庫(kù)

七、總結(jié)與展望

7.1 技術(shù)總結(jié)

實(shí)現(xiàn)了0延遲的顏色采樣

開(kāi)發(fā)了符合現(xiàn)代審美的UI組件

解決了高DPI屏幕下的顯示問(wèn)題

7.2 優(yōu)化方向

增加歷史顏色記錄

支持顏色格式轉(zhuǎn)換

添加插件系統(tǒng)

到此這篇關(guān)于使用Python開(kāi)發(fā)一個(gè)現(xiàn)代化屏幕取色器的文章就介紹到這了,更多相關(guān)Python屏幕取色器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論