婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 如何使用Python做個自定義動態(tài)壁紙

如何使用Python做個自定義動態(tài)壁紙

熱門標(biāo)簽:高德地圖標(biāo)注收入咋樣 怎么辦理400客服電話 B52系統(tǒng)電梯外呼顯示E7 企業(yè)微信地圖標(biāo)注 地圖標(biāo)注多個 沈陽防封電銷電話卡 銀川電話機(jī)器人電話 鶴壁手機(jī)自動外呼系統(tǒng)違法嗎 萊蕪電信外呼系統(tǒng)

使用Python做個自定義動態(tài)壁紙

首先一起來看看最終實(shí)現(xiàn)的自定義動態(tài)壁紙效果:

接我

接下來,我們開始介紹這個自定義動態(tài)桌面的制作過程。

一、核心功能設(shè)計(jì)

總體來說,我們需要實(shí)現(xiàn)將自己喜歡的視頻轉(zhuǎn)成一個動態(tài)桌面,知識點(diǎn)主要包含了對視頻提取解析,視頻輪播,PyQt5窗體設(shè)置,桌面句柄獲取,自定義動態(tài)桌面壁紙實(shí)現(xiàn)等。

大致可以整理出我們需要分為以下幾步完成:

  1. UI排版布局設(shè)計(jì),確認(rèn)動態(tài)壁紙功能設(shè)計(jì)
  2. 加載視頻,對視頻進(jìn)行預(yù)覽讀取,保存視頻路徑等
  3. 動態(tài)壁紙功能實(shí)現(xiàn)應(yīng)用,獲取桌面句柄,輪播加載視頻
  4. 關(guān)閉動態(tài)壁紙,在線壁紙資源獲取等

二、實(shí)現(xiàn)步驟

之前有粉絲反饋說,想自己跟著文章自己敲敲代碼,但是不知道具體需要哪些模塊、包文件,后面我就把所有用到模塊先放出來。

import os
import sys
from subprocess import call
from threading import Thread
from time import sleep

import cv2
from PyQt5 import QtCore,  QtWidgets
from PyQt5.QtCore import Qt,  QTimer
from PyQt5.QtGui import QImage, QPixmap, QIcon

from PyQt5.QtWidgets import QGridLayout, QPushButton, QMainWindow, QFileDialog, QLabel, QSystemTrayIcon, \

    QAction, QMenu, QMessageBox
from os import path as pathq

1. UI排版布局設(shè)計(jì)

根據(jù)動態(tài)壁紙所需要的功能,首先進(jìn)行UI布局設(shè)計(jì),我們這次還是使用的pyqt5。主要包含了加載讀取本地視頻、視頻加載預(yù)覽、動態(tài)壁紙應(yīng)用、動態(tài)壁紙關(guān)閉等。核心設(shè)計(jì)代碼如下:

# author:Dragon少年
def setupUi(self, MainWindow):
    MainWindow.setObjectName("MainWindow")
    MainWindow.resize(505, 615)
    MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
    self.centralwidget = QtWidgets.QWidget(MainWindow)
    self.centralwidget.setObjectName("centralwidget")
    self.pushButton = QtWidgets.QPushButton(self.centralwidget)
    self.pushButton.setGeometry(QtCore.QRect(22, 10, 89, 31))
    self.pushButton.setObjectName("pushButton")
    self.pushButton.clicked.connect(self.openmp4)
    self.pushButton.setStyleSheet(
        '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
    self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
    self.groupBox.setGeometry(QtCore.QRect(22, 50, 452, 351))
    self.groupBox.setObjectName("groupBox")
    self.widget = QtWidgets.QWidget(self.groupBox)
    self.widget.setGeometry(QtCore.QRect(11, 20, 430, 291))
    self.widget.setObjectName("widget")
    self.gridLayout_3 = QtWidgets.QGridLayout(self.widget)
    self.gridLayout_3.setObjectName("gridLayout_3")
    self.label = QLabel(self)
    self.label.resize(400, 300)
    self.label.setText("Waiting for video...")
    self.gridLayout_3.addWidget(self.label)
    self.close_widget = QtWidgets.QWidget(self.centralwidget)
    self.close_widget.setGeometry(QtCore.QRect(420, 0, 93, 41))
    self.close_widget.setObjectName("close_widget")
    self.close_layout = QGridLayout()  # 創(chuàng)建左側(cè)部件的網(wǎng)格布局層
    self.close_widget.setLayout(self.close_layout)  # 設(shè)置左側(cè)部件布局為網(wǎng)格
    self.left_close = QPushButton("")  # 關(guān)閉按鈕
    self.left_close.clicked.connect(self.close)
    self.left_visit = QPushButton("")  # 空白按鈕
    #self.left_visit.clicked.connect(MainWindow.big)
    self.left_mini = QPushButton("")  # 最小化按鈕
    self.left_mini.clicked.connect(MainWindow.mini)
    self.close_layout.addWidget(self.left_mini, 0, 0, 1, 1)
    self.close_layout.addWidget(self.left_close, 0, 2, 1, 1)
    self.close_layout.addWidget(self.left_visit, 0, 1, 1, 1)
    self.left_close.setFixedSize(15, 15)  # 設(shè)置關(guān)閉按鈕的大小
    self.left_visit.setFixedSize(15, 15)  # 設(shè)置按鈕大小
    self.left_mini.setFixedSize(15, 15)  # 設(shè)置最小化按鈕大小
    self.left_close.setStyleSheet(
        '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')
    self.left_visit.setStyleSheet(
        '''QPushButton{background:#F7D674;border-radius:5px;}QPushButton:hover{background:yellow;}''')
    self.left_mini.setStyleSheet(
        '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')
    self.horizontalLayout = QtWidgets.QHBoxLayout(self.close_widget)
    self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
    self.horizontalLayout.setObjectName("horizontalLayout")
    self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
    self.pushButton_2.setGeometry(QtCore.QRect(77, 440, 133, 41))
    self.pushButton_2.setObjectName("pushButton_2")
    self.pushButton_2.clicked.connect(self.play)
    self.pushButton_2.setStyleSheet(
        '''QPushButton{background:#6DDF6D;border-radius:5px;}QPushButton:hover{background:green;}''')
    self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
    self.pushButton_3.setGeometry(QtCore.QRect(308, 440, 111, 41))
    self.pushButton_3.setObjectName("pushButton_3")
    self.pushButton_3.clicked.connect(self.close_wall)
    self.pushButton_3.setStyleSheet(
        '''QPushButton{background:#F76677;border-radius:5px;}QPushButton:hover{background:red;}''')
    self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
    self.pushButton_4.setGeometry(QtCore.QRect(187, 540, 133, 21))
    self.pushButton_4.setObjectName("pushButton_4")
    self.pushButton_4.clicked.connect(self.openurl)
    self.pushButton_4.setStyleSheet(
        '''QPushButton{background:#222225;color:white;border-radius:5px;}QPushButton:hover{background:#222225;color:skyblue}''')
    MainWindow.setCentralWidget(self.centralwidget)
    self.menubar = QtWidgets.QMenuBar(MainWindow)
    self.menubar.setGeometry(QtCore.QRect(0, 0, 505, 23))
    self.menubar.setObjectName("menubar")
    MainWindow.setMenuBar(self.menubar)
    self.statusbar = QtWidgets.QStatusBar(MainWindow)
    self.statusbar.setObjectName("statusbar")
    MainWindow.setStatusBar(self.statusbar)
    self.retranslateUi(MainWindow)
    QtCore.QMetaObject.connectSlotsByName(MainWindow)
    self.groupBox.setStyleSheet('''
    color:white
    ''')
    MainWindow.setWindowOpacity(0.95)  # 設(shè)置窗口透明度
    MainWindow.setAttribute(Qt.WA_TranslucentBackground)
    MainWindow.setWindowFlag(Qt.FramelessWindowHint)  # 隱藏邊框
# author:Dragon少年
def retranslateUi(self, MainWindow):
    _translate = QtCore.QCoreApplication.translate
    MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
    self.pushButton.setText(_translate("MainWindow", "從本地選擇"))
    self.groupBox.setTitle(_translate("MainWindow", "預(yù)覽"))
    self.pushButton_2.setText(_translate("MainWindow", "應(yīng)用"))
    self.pushButton_3.setText(_translate("MainWindow", "關(guān)閉壁紙"))
    self.pushButton_4.setText(_translate("MainWindow", "在線資源"))

UI實(shí)現(xiàn)效果如下:

UI布局設(shè)計(jì)完成,下面我們開始進(jìn)行視頻讀取加載、預(yù)覽功能實(shí)現(xiàn)。

2. 視頻加載預(yù)覽

接來下我們可以根據(jù)自己喜歡的視頻,從本地讀取視頻,并且將視頻預(yù)覽播放顯示。這里視頻演示,博主還是用之前的那篇紫顏小姐姐的跳舞視頻進(jìn)行演示。

讀取視頻:

讀取視頻我們可以通過打開文件對話框,選擇視頻資源,開啟一個子線程用來進(jìn)行視頻開啟停止播放。核心代碼如下:

# author:Dragon少年
def openmp4(self):
    try:
        global path
        path, filetype = QFileDialog.getOpenFileName(None, "選擇文件", '.',
                                                     "視頻文件(*.AVI;*.mov;*.rmvb;*.rm;*.FLV;*.mp4;*.3GP)")  # ;;All Files (*)
        if path == "":  # 未選擇文件
            return

        self.slotStart()
        t = Thread(target=self.Stop)
        t.start()  # 啟動線程,即讓線程開始執(zhí)行
    except Exception as e:
        print (e)

視頻流讀取播放:

接下來,我們需要對視頻文件進(jìn)行按幀讀取加載顯示,并通過計(jì)時器實(shí)現(xiàn)動畫效果。核心代碼如下:

# author:Dragon少年
def slotStart(self):
    videoName = path
    if videoName != "":  # “”為用戶取消
        self.cap = cv2.VideoCapture(videoName)
        self.timer_camera.start(50)
        self.timer_camera.timeout.connect(self.openFrame)

# author:Dragon少年
def openFrame(self):
    if (self.cap.isOpened()):
        ret, self.frame = self.cap.read()
        if ret:
            frame = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
            if self.detectFlag == True:
                # 檢測代碼self.frame
                self.label_num.setText("There are " + str(5) + " people.")
            height, width, bytesPerComponent = frame.shape
            bytesPerLine = bytesPerComponent * width
            q_image = QImage(frame.data, width, height, bytesPerLine,
                             QImage.Format_RGB888).scaled(self.label.width(), self.label.height())
            self.label.setPixmap(QPixmap.fromImage(q_image))
        else:
            self.cap.release()
            self.timer_camera.stop()  # 停止計(jì)時器

至此,我們已經(jīng)可以實(shí)現(xiàn)視頻讀取加載,并且進(jìn)行視頻預(yù)覽了,效果如下:

3. 動態(tài)壁紙功能實(shí)現(xiàn)

實(shí)現(xiàn)桌面壁紙?zhí)鎿Q,我們首先需要獲取桌面句柄找到桌面窗體,覆寫桌面窗體、調(diào)用加載的視頻流,播放動態(tài)壁紙。

獲取桌面句柄:

# author:Dragon少年
def pretreatmentHandle():
    hwnd = win32gui.FindWindow("Progman", "Program Manager")
    win32gui.SendMessageTimeout(hwnd, 0x052C, 0, None, 0, 0x03E8)
    hwnd_WorkW = None
    while 1:
        hwnd_WorkW = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
        if not hwnd_WorkW:
            continue
        hView = win32gui.FindWindowEx(hwnd_WorkW, None, "SHELLDLL_DefView", None)
        # print('hwmd_hView: ', hView)
        if not hView:
            continue
        h = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
        while h:
            win32gui.SendMessage(h, 0x0010, 0, 0)  # WM_CLOSE
            h = win32gui.FindWindowEx(None, hwnd_WorkW, "WorkerW", None)
        break
    return hwnd

桌面覆寫:

我們可以創(chuàng)建一個類,對窗體進(jìn)行繼承,進(jìn)行視頻流加載讀取播放。核心代碼如下:

# author:Dragon少年
class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.player = QMediaPlayer()
        self.player.setNotifyInterval(10000)
        self.player.setVideoOutput(self.ui.videowidget)
        self.player.setMuted(bool(1 - self.player.isMuted()))
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.setupUi(self)
        self.go()


 # author: Dragon少年
    def go(self):
        self.ui.videowidget.setFullScreen(True)

        with open("./filename.txt", 'r', encoding='utf-8') as f:
            file_name = f.read()
            if file_name =='':
                file_name = 'lkf.mp4'
        print (file_name)
        if not os.path.exists(file_name):
            sys.exit()
        media = QMediaContent(QUrl(file_name))
        self.player.setMedia(media)
        self.mplayList = QMediaPlaylist()
        self.mplayList.addMedia(QMediaContent(QUrl.fromLocalFile(file_name)))
        self.player.setPlaylist(self.mplayList)
        self.mplayList.setPlaybackMode(QMediaPlaylist.CurrentItemInLoop)
        win_hwnd = int(self.winId())
        video_h = int(self.ui.videowidget.winId())
        win32gui.SetParent(win_hwnd, h)
        win32gui.SetParent(video_h, h)
        win32gui.SetParent(video_h, win_hwnd)
        self.player.play()

這里我們把上面的py文件直接打包成exe文件,接下來我們在“應(yīng)用”控件上進(jìn)行事件綁定,直接調(diào)用exe執(zhí)行,實(shí)現(xiàn)動態(tài)壁紙播放應(yīng)用功能。核心代碼如下:

def play(self):
     if path == '':
         reply = QtWidgets.QMessageBox.question(self, '提示',
                                                "未加載選擇視頻",
                                                QtWidgets.QMessageBox.Yes)
         return
     with open("./filename.txt", 'w', encoding='utf-8') as f:
         f.truncate(0)
         print(f.write(str(path)))
     try:
         try:
             call('taskkill /F /IM play.exe')
         except:
             pass
         os.system('start play.exe')
     except:
         pass
     try:
         if self.cap != []:
             self.cap.release()
             self.timer_camera.stop()  # 停止計(jì)時器
         else:
             Warming = QMessageBox.warning(self, "Warming", "Push the left upper corner button to Quit.",
                                           QMessageBox.Yes)
     except:
         pass

這樣,我們就完成了動態(tài)壁紙加載應(yīng)用功能了,效果如下:

4. 關(guān)閉動態(tài)壁紙

最后我們再實(shí)現(xiàn)下當(dāng)前動態(tài)壁紙播放關(guān)閉功能,我們需要對當(dāng)前桌面視頻播放進(jìn)行釋放取消。代碼如下:

# author:Dragon少年
 def close_wall(self):
     try:
         call('taskkill /F /IM play.exe')
     except:
         pass

效果如下:

至此,整個自定義動態(tài)桌面壁紙功能就全部完成了,下面我們一起運(yùn)行下看看動態(tài)壁紙效果。

到此這篇關(guān)于使用Python做個自定義動態(tài)壁紙的文章就介紹到這了,更多相關(guān)Python做動態(tài)壁紙內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python實(shí)現(xiàn)雙軸組合圖表柱狀圖和折線圖的具體流程
  • 用Python做個個性的動畫掛件讓桌面不單調(diào)
  • 如何用Python寫一個簡單的通訊錄
  • python實(shí)現(xiàn)多個視頻文件合成畫中畫效果
  • 自己用python做的一款超炫酷音樂播放器
  • Python做個自定義動態(tài)壁紙還可以放視頻
  • 分析總結(jié)Python數(shù)據(jù)化運(yùn)營KMeans聚類
  • python中的zip模塊
  • 總結(jié)分析python數(shù)據(jù)化運(yùn)營關(guān)聯(lián)規(guī)則
  • python項(xiàng)目--使用Tkinter的日歷GUI應(yīng)用程序

標(biāo)簽:銀川 呼倫貝爾 葫蘆島 安慶 湘西 呼倫貝爾 三亞 烏魯木齊

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《如何使用Python做個自定義動態(tài)壁紙》,本文關(guān)鍵詞  如何,使用,Python,做個,自定義,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《如何使用Python做個自定義動態(tài)壁紙》相關(guān)的同類信息!
  • 本頁收集關(guān)于如何使用Python做個自定義動態(tài)壁紙的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久综合网色—综合色88| 国产精品色哟哟| 国产一区 二区| 日韩精品电影一区亚洲| 亚洲人成网站影音先锋播放| 久久九九久久九九| 国产肉丝袜一区二区| 亚洲少妇最新在线视频| 一区二区三区毛片| 首页综合国产亚洲丝袜| 久久99精品久久只有精品| 热久久一区二区| 国产精品18久久久久久久久久久久| 国产精品99久| 色先锋资源久久综合| 欧美日高清视频| 国产亚洲精品久| 久久精品视频在线免费观看| 久久精品一区四区| 一区二区三区免费看视频| 亚洲色图在线看| 国产suv一区二区三区88区| 色爱区综合激月婷婷| 在线播放/欧美激情| 国产欧美日韩综合精品一区二区| 国产精品美女久久久久aⅴ| 亚洲国产va精品久久久不卡综合| 日本亚洲三级在线| 北条麻妃国产九九精品视频| 在线观看亚洲精品视频| 精品久久久久久久久久久院品网| 亚洲欧美日韩国产手机在线| 欧美日韩成人高清| 亚洲人妖av一区二区| 久久草av在线| 欧美xxxx老人做受| 一区二区视频在线| 国精产品一区一区三区mba桃花| 9色porny自拍视频一区二区| 精品福利在线导航| 日本美女视频一区二区| 欧美自拍偷拍一区| 一区二区三区免费| 日韩欧美一区二区免费| 亚洲午夜影视影院在线观看| 色成人在线视频| 午夜一区二区三区在线观看| 91麻豆免费观看| 亚洲国产精品久久久久婷婷884| 国产高清久久久| 成人免费在线视频| 91在线视频免费观看| 午夜精品一区在线观看| 欧美大片一区二区| 国产精品资源在线看| 亚洲日韩欧美一区二区在线| 色综合天天性综合| 三级欧美在线一区| 国产欧美日韩综合| 欧美自拍偷拍午夜视频| 狠狠色综合播放一区二区| 亚洲日本丝袜连裤袜办公室| 欧美日韩第一区日日骚| 成人av网址在线| 国产一级精品在线| 免费观看在线色综合| 亚洲欧洲综合另类| 国产亚洲欧洲一区高清在线观看| 欧美日韩国产综合一区二区| 成人高清免费在线播放| 日本午夜一区二区| 一区二区免费看| 亚洲美女精品一区| 中文字幕一区二区三区在线播放| 日韩女同互慰一区二区| 不卡的av网站| 国产高清一区日本| 麻豆精品久久精品色综合| 日韩国产一二三区| 免费xxxx性欧美18vr| 日韩中文字幕不卡| 视频一区视频二区中文字幕| 亚洲国产综合91精品麻豆| 亚洲无线码一区二区三区| 一区二区欧美视频| 亚洲愉拍自拍另类高清精品| 亚洲狠狠丁香婷婷综合久久久| 中文字幕在线不卡| 亚洲国产综合91精品麻豆| 日日夜夜免费精品| 精品一二三四在线| 99国产欧美另类久久久精品| 色综合天天综合网天天狠天天| 成人国产精品免费观看视频| 91在线国产观看| 在线免费精品视频| 欧美高清性hdvideosex| 欧美成人激情免费网| 国产亚洲美州欧州综合国| 亚洲猫色日本管| 美女www一区二区| 国产a级毛片一区| 欧美四级电影网| 国产亚洲精品bt天堂精选| 亚洲自拍偷拍网站| 国产精品资源在线观看| 精品视频全国免费看| 久久久99免费| 丝袜美腿亚洲色图| 欧美mv日韩mv| 一区二区三区在线看| 国产999精品久久久久久绿帽| 在线精品视频一区二区| 2019国产精品| 精一区二区三区| 欧美日韩一区中文字幕| 中文字幕一区二区视频| 国产乱淫av一区二区三区| 欧美另类久久久品| 日韩一区在线播放| 国产成人免费视频网站 | 午夜精品久久久久久久久久| 高清国产一区二区| 久久人人97超碰com| 激情六月婷婷久久| 日韩欧美中文字幕一区| 免费在线观看精品| 亚洲女同女同女同女同女同69| av中文一区二区三区| 亚洲视频在线一区| 91麻豆自制传媒国产之光| 一区二区激情小说| 欧美精品日日鲁夜夜添| 亚洲午夜精品17c| 欧美一卡2卡三卡4卡5免费| 免费高清成人在线| 久久综合国产精品| 色婷婷激情综合| 亚洲成精国产精品女| 久久久综合精品| 5566中文字幕一区二区电影| 国产成人丝袜美腿| 婷婷综合在线观看| 亚洲欧洲国产日本综合| 日韩一区二区影院| 国产成人高清在线| 日韩精品高清不卡| 亚洲天天做日日做天天谢日日欢| 欧洲色大大久久| av亚洲精华国产精华| 国产一区二区三区在线看麻豆| 亚洲专区一二三| 中文字幕一区二区三区视频| 久久综合中文字幕| 久久久久九九视频| 3d动漫精品啪啪1区2区免费| 欧美群妇大交群中文字幕| 欧美色国产精品| 91精品国产麻豆国产自产在线| 欧美一区二区三区视频免费| 91精品国产色综合久久ai换脸| 7777精品伊人久久久大香线蕉超级流畅| 色婷婷综合久久久久中文| 日本精品免费观看高清观看| 欧美性感一类影片在线播放| 91麻豆精品久久久久蜜臀| 日韩欧美高清在线| 国产精品另类一区| 亚洲va韩国va欧美va| 日本亚洲欧美天堂免费| 国产精品综合久久| 一区二区三区免费在线观看| 国产ts人妖一区二区| 色999日韩国产欧美一区二区| 日韩一区二区三区在线| 乱中年女人伦av一区二区| 91精品久久久久久久久99蜜臂| 日韩国产高清影视| 一区二区三区四区不卡视频| 欧美一区二区视频在线观看2020 | 91同城在线观看| 麻豆国产一区二区| 欧美放荡的少妇| 国产片一区二区| 色婷婷久久久综合中文字幕| 亚洲最色的网站| 精品国产免费人成在线观看| 成人ar影院免费观看视频| 乱一区二区av| 青青草国产精品亚洲专区无| 亚洲成av人片一区二区梦乃| 亚洲精品福利视频网站| 国产精品久久久久久久久晋中| 丁香另类激情小说| 亚洲国产aⅴ天堂久久| 91香蕉视频在线| 色8久久人人97超碰香蕉987| 懂色中文一区二区在线播放| 另类小说图片综合网| 国产电影一区在线|