当前位置: 代码网 > it编程>编程语言>C/C++ > Opencv与PyQt5设计一个摄像头界面

Opencv与PyQt5设计一个摄像头界面

2024年08月02日 C/C++ 我要评论
这是我见过很详细的教你如何使用的PyQt5来完成UI界面设计的,专注于UI界面设计。对我而言,这教程就像是一个实用工具,因为我只需要能够显示图像并展示模型推理的结果即可。最近一直在努力改进网络和编写脚本,已经有一段时间没写博客了。因此,我打算重新整理这位博主的内容,争取以更简单的方式呈现。

一、前言

本篇的内容是学习的这一位博主的:程序界面设计_doc_cheng的博客-csdn博客

这是我见过很详细的教你如何使用的pyqt5来完成ui界面设计的,专注于ui界面设计。对我而言,这教程就像是一个实用工具,因为我只需要能够显示图像并展示模型推理的结果即可。

最近一直在努力改进网络和编写脚本,已经有一段时间没写博客了。因此,我打算重新整理这位博主的内容,争取以更简单的方式呈现。

二、ui界面设计

预览图如下所示:

8fac23e1784c492dbac4eb0b38586d74.png

这里我们主要讲解代码部分,ui文件我会直接的提供给大家,大家可以下载下来后再对照着学习。

三、代码讲解

当我们使用pyuic生成代码的时候,一般情况下这个类下有两个函数:setupui和retranslateui。

8bc3d9c827944499805159a65578684e.png

一般而言,这两个方法用于设置用户界面的初始化和翻译文本。在 setupui 中,会设置窗口、布局、按钮、文本框等元素的属性和初始状态;而在 retranslateui 中,会设置用户界面元素的文本内容。

如果我们只是想要一个像上面的一个浏览图,你可以直接使用下面的代码直接进行预览,它本身并没有任何的功能,只是将ui界面的布局展示出来了,要想做更多的事情,那就需要给这个类补充更多的功能。

from oboardcamdisp import ui_mainwindow

import sys
from pyqt5.qtwidgets import qapplication, qmainwindow

class camshow(qmainwindow, ui_mainwindow):
    def __init__(self, parent=none):
        super(camshow, self).__init__(parent)
        self.setupui(self)

if __name__ == '__main__':
    app = qapplication(sys.argv)
    ui=camshow()
    ui.show()
    sys.exit(app.exec_())

你随意的点击滑动这些控件是没有任何用的,这里的camshow 类继承自 qmainwindow 和 ui_mainwindow,通过调用 setupui 方法初始化界面。

1,滑动条与微调框的连接

当我运行上面的文件时候,我们发现移动滑动条或者给微调框调整是各改各的,这里我们可以通过将滑块的 valuechanged 信号连接到对应微调框的 setvalue 槽,以及将微调框的 valuechanged 信号连接到对应滑块的 setvalue 槽。

    def prepsliders(self):
        self.redcolorsld.valuechanged.connect(self.redcolorspb.setvalue)
        self.redcolorspb.valuechanged.connect(self.redcolorsld.setvalue)
        self.greencolorsld.valuechanged.connect(self.greencolorspb.setvalue)
        self.greencolorspb.valuechanged.connect(self.greencolorsld.setvalue)
        self.bluecolorsld.valuechanged.connect(self.bluecolorspb.setvalue)
        self.bluecolorspb.valuechanged.connect(self.bluecolorsld.setvalue)
        self.exptimesld.valuechanged.connect(self.exptimespb.setvalue)
        self.exptimespb.valuechanged.connect(self.exptimesld.setvalue)
        self.gainsld.valuechanged.connect(self.gainspb.setvalue)
        self.gainspb.valuechanged.connect(self.gainsld.setvalue)
        self.brightsld.valuechanged.connect(self.brightspb.setvalue)
        self.brightspb.valuechanged.connect(self.brightsld.setvalue)
        self.contrastsld.valuechanged.connect(self.contrastspb.setvalue)
        self.contrastspb.valuechanged.connect(self.contrastsld.setvalue)

70329a60de1940d7a3bef5505e825acb.png

这里通信成功,像上面的self.redcolorsld和self.redcolorspb都是继承的ui_mainwindow下面的,名字,还有数值都需要自己去修改。

其实也就是这下面的两个地方:

38cc8250e3e540ef801349f7a48c3254.png

2,相机的初始化和参数设置

这里通过 cv2.videocapture 初始化了相机,并设置了一些相机参数,例如曝光时间、增益、亮度和对比度。通过连接滑动条和微调框,能使用户能够动态地调整这些参数。

    def prepcamera(self):
        try:
            self.camera = cv2.videocapture(0)
            self.msgte.clear()
            self.msgte.append('oboard camera connected.')
            self.msgte.setplaintext()
        except exception as e:
            self.msgte.clear()
            self.msgte.append(str(e))

    def prepparameters(self):
        self.recordpath='d:/pythonproject/pythonproject1/opencvpyqt5/'
        self.filepathle.settext(self.recordpath)   # 默认显示
        self.recordflag=0
        self.image_num=0
        self.r=1
        self.g=1
        self.b=1

        self.exptimesld.setvalue(self.camera.get(15))
        self.setexposure()
        self.gainsld.setvalue(self.camera.get(14))
        self.setgain()
        self.brightsld.setvalue(self.camera.get(10))
        self.setbrightness()
        self.contrastsld.setvalue(self.camera.get(11))
        self.setcontrast()
        self.msgte.clear()

a43c831a74af4352bb694d1c1745f8aa.png

3,界面按钮和相关功能

在这一步中,为界面上的按钮添加了一些功能,例如启动相机、停止相机、录像等。通过连接这些按钮的点击事件,我们实现了相应的功能。特别是,通过 callbackfunctions 函数,我们将按钮的点击事件与后台函数进行了关联。

    def startcamera(self):
        self.showbt.setenabled(false)
        self.stopbt.setenabled(true)
        self.recordbt.setenabled(true)
        self.grayimgckb.setenabled(true)
        if self.grayimgckb.ischecked() == 0:
            self.redcolorsld.setenabled(true)
            self.redcolorspb.setenabled(true)
            self.greencolorsld.setenabled(true)
            self.greencolorspb.setenabled(true)
            self.bluecolorsld.setenabled(true)
            self.bluecolorspb.setenabled(true)
        self.exptimesld.setenabled(true)
        self.exptimespb.setenabled(true)
        self.gainsld.setenabled(true)
        self.gainspb.setenabled(true)
        self.brightsld.setenabled(true)
        self.brightspb.setenabled(true)
        self.contrastsld.setenabled(true)
        self.contrastspb.setenabled(true)
        self.recordbt.settext('录像')
        self.timer.start(1)
        self.timelb = time.perf_counter()

在最开始运行的时候,有些需要禁用,比如,比如在上面的地方灰度的checkbox没有被点击可以调试r、g、b。

    def stopcamera(self):
        if self.stopbt.text()=='暂停':
            self.stopbt.settext('继续')
            self.recordbt.settext('保存')
            self.timer.stop()
        elif self.stopbt.text()=='继续':
            self.stopbt.settext('暂停')
            self.recordbt.settext('录像')
            self.timer.start(1)

这是一个很简单的逻辑,在这个函数中,如果当前按钮的文本为 ‘暂停’,则将其设置为 ‘继续’ ,并将录像按钮的文本设置为 ‘保存’,最后停止计时器;如果当前按钮的文本为 ‘继续',则将其设置为 ‘暂停’,将录像按钮的文本设置为 ‘录像’ ,并重新启动计时器。

    def recordcamera(self):
        tag=self.recordbt.text()
        if tag=='保存':
            try:
                image_name=self.recordpath+'image'+time.strftime('%y%m%d%h%m%s',time.localtime(time.time()))+'.jpg'
                print(image_name)
                cv2.imwrite(image_name, self.image)
                self.msgte.clear()
                self.msgte.setplaintext('image saved.')
            except exception as e:
                self.msgte.clear()
                self.msgte.setplaintext(str(e))
        elif tag == '录像':
            self.recordbt.settext('停止')

            video_name = self.recordpath + 'video' + time.strftime('%y%m%d%h%m%s',time.localtime(time.time())) + '.avi'
            fps = self.fmratelcd.value()
            size = (self.image.shape[1],self.image.shape[0])
            fourcc = cv2.videowriter_fourcc('m', 'j', 'p', 'g')
            self.video_writer = cv2.videowriter(video_name, fourcc,self.camera.get(5), size)
            self.recordflag=1
            self.msgte.setplaintext('video recording...')
            self.stopbt.setenabled(false)
            self.exitbt.setenabled(false)
        elif tag == '停止':
            self.recordbt.settext('录像')
            self.video_writer.release()
            self.recordflag = 0
            self.msgte.setplaintext('video saved.')
            self.stopbt.setenabled(true)
            self.exitbt.setenabled(true)

如果按钮的文本为 '保存',则执行保存图片的操作。首先构造图片文件名,使用 cv2.imwrite 将当前图像保存为 jpg 文件,然后清空消息显示框并显示保存成功或者错误信息。如果按钮的文本为 '录像',则执行开始录像的操作。构造视频文件名,设置录像相关参数(帧率、大小等),创建 cv2.videowriter 对象开始录像,并在消息显示框中显示录像信息。同时禁用停止按钮和退出按钮,防止在录像时进行其他操作。如果按钮的文本为 '停止',则执行停止录像的操作。将按钮文本设置为 '录像',释放 cv2.videowriter 对象,停止录像标志,显示录像保存成功的消息,并启用停止按钮和退出按钮。

4,图像处理与显示

    def coloradjust(self, img):
        try:
            b = img[:, :, 0]
            g = img[:, :, 1]
            r = img[:, :, 2]

            # 根据滑动条的值进行颜色通道的调整
            b = b * self.b
            g = g * self.g
            r = r * self.r

            img_adjusted = img.copy()
            img_adjusted[:, :, 0] = b
            img_adjusted[:, :, 1] = g
            img_adjusted[:, :, 2] = r

            return img_adjusted
        except exception as e:
            self.msgte.setplaintext(str(e))

    def dispimg(self):
        if self.grayimgckb.ischecked():
            img = cv2.cvtcolor(self.image, cv2.color_bgr2gray)
        else:
            img = cv2.cvtcolor(self.image, cv2.color_bgr2rgb)
        qimg = qimage2ndarray.array2qimage(img)
        self.displb.setpixmap(qpixmap(qimg))
        self.displb.show()

coloradjust函数用于进行颜色调整。然后,通过 qimage2ndarray 将处理后的图像转换为 qimage,最后使用 qpixmap 在界面上的 displb 标签上显示图像。这样,我们完成了图像处理与显示的步骤。

5,使用回调函数将功能与控件进行连接

    def callbackfunctions(self):
        self.filepathbt.clicked.connect(self.setfilepath)
        self.showbt.clicked.connect(self.startcamera)
        self.stopbt.clicked.connect(self.stopcamera)
        self.recordbt.clicked.connect(self.recordcamera)
        self.exitbt.clicked.connect(self.exitapp)
        self.grayimgckb.statechanged.connect(self.setgray)
        self.exptimesld.valuechanged.connect(self.setexposure)
        self.gainsld.valuechanged.connect(self.setgain)
        self.brightsld.valuechanged.connect(self.setbrightness)
        self.contrastsld.valuechanged.connect(self.setcontrast)
        self.redcolorsld.valuechanged.connect(self.setr)
        self.greencolorsld.valuechanged.connect(self.setg)
        self.bluecolorsld.valuechanged.connect(self.setb)
    def setr(self):
        r=self.redcolorsld.value()
        self.r=r/255
    def setg(self):
        g=self.greencolorsld.value()
        self.g=g/255
    def setb(self):
        b=self.bluecolorsld.value()
        self.b=b/255
    def setcontrast(self):
        contrast_toset=self.contrastsld.value()
        try:
            self.camera.set(11,contrast_toset)
            self.msgte.setplaintext('the contrast is set to ' + str(self.camera.get(11)))
        except exception as e:
            self.msgte.setplaintext(str(e))
    def setbrightness(self):
        brightness_toset=self.brightsld.value()
        try:
            self.camera.set(10,brightness_toset)
            self.msgte.setplaintext('the brightness is set to ' + str(self.camera.get(10)))
        except exception as e:
            self.msgte.setplaintext(str(e))
    def setgain(self):
        gain_toset=self.gainsld.value()
        try:
            self.camera.set(14,gain_toset)
            self.msgte.setplaintext('the gain is set to '+str(self.camera.get(14)))
        except exception as e:
            self.msgte.setplaintext(str(e))
    def setexposure(self):
        try:
            exposure_time_toset=self.exptimesld.value()
            self.camera.set(15,exposure_time_toset)
            self.msgte.setplaintext('the exposure time is set to '+str(self.camera.get(15)))
        except exception as e:
            self.msgte.setplaintext(str(e))
    def setgray(self):
        if self.grayimgckb.ischecked():
            self.redcolorsld.setenabled(false)
            self.redcolorspb.setenabled(false)
            self.greencolorsld.setenabled(false)
            self.greencolorspb.setenabled(false)
            self.bluecolorsld.setenabled(false)
            self.bluecolorspb.setenabled(false)
        else:
            self.redcolorsld.setenabled(true)
            self.redcolorspb.setenabled(true)
            self.greencolorsld.setenabled(true)
            self.greencolorspb.setenabled(true)
            self.bluecolorsld.setenabled(true)
            self.bluecolorspb.setenabled(true)

四、其他补充

如果报错pyqt下载不了,是缺少了c++,下一个visual studio然后安装一个c++桌面开发就可以了。

如果运行出现:

说的是sip版本不对,这个不影响运行,可以不用理会。

五、资源下载

pyqt5-opencv-uidesign/camshow at main · auorui/pyqt5-opencv-uidesign (github.com)

主函数文件:

from oboardcamdisp import ui_mainwindow
import sys
from pyqt5.qtwidgets import qapplication,qmainwindow,qfiledialog
from pyqt5.qtcore import qtimer,qcoreapplication
from pyqt5.qtgui import qpixmap
import cv2
import qimage2ndarray
import time

class camshow(qmainwindow,ui_mainwindow):
    def __del__(self):
        try:
            self.camera.release()  # 释放资源
        except:
            return

    def __init__(self,parent=none):
        super(camshow,self).__init__(parent)
        self.setupui(self)
        self.prepsliders()
        self.prepwidgets()
        self.prepparameters()
        self.callbackfunctions()
        self.timer=qtimer()
        self.timer.timeout.connect(self.timeroutfun)

    # 滑动条与微调框的连接
    def prepsliders(self):
        self.redcolorsld.valuechanged.connect(self.redcolorspb.setvalue)
        self.redcolorspb.valuechanged.connect(self.redcolorsld.setvalue)
        self.greencolorsld.valuechanged.connect(self.greencolorspb.setvalue)
        self.greencolorspb.valuechanged.connect(self.greencolorsld.setvalue)
        self.bluecolorsld.valuechanged.connect(self.bluecolorspb.setvalue)
        self.bluecolorspb.valuechanged.connect(self.bluecolorsld.setvalue)
        self.exptimesld.valuechanged.connect(self.exptimespb.setvalue)
        self.exptimespb.valuechanged.connect(self.exptimesld.setvalue)
        self.gainsld.valuechanged.connect(self.gainspb.setvalue)
        self.gainspb.valuechanged.connect(self.gainsld.setvalue)
        self.brightsld.valuechanged.connect(self.brightspb.setvalue)
        self.brightspb.valuechanged.connect(self.brightsld.setvalue)
        self.contrastsld.valuechanged.connect(self.contrastspb.setvalue)
        self.contrastspb.valuechanged.connect(self.contrastsld.setvalue)

    # 相机的初始化和参数设置
    def prepcamera(self):
        try:
            self.camera=cv2.videocapture(0)
            self.msgte.clear()
            self.msgte.append('oboard camera connected.')
            self.msgte.setplaintext()
        except exception as e:
            self.msgte.clear()
            self.msgte.append(str(e))

    def prepparameters(self):
        self.recordflag = 0
        self.recordpath ='d:/pythonproject/pythonproject1/opencvpyqt5/camshow'
        self.filepathle.settext(self.recordpath)
        self.image_num = 0
        self.r = 1
        self.g = 1
        self.b = 1

        self.exptimesld.setvalue(self.camera.get(15))
        self.setexposure()
        self.gainsld.setvalue(self.camera.get(14))
        self.setgain()
        self.brightsld.setvalue(self.camera.get(10))
        self.setbrightness()
        self.contrastsld.setvalue(self.camera.get(11))
        self.setcontrast()
        self.msgte.clear()

    # 相机的初始化和参数设置
    def startcamera(self):
        self.showbt.setenabled(false)
        self.stopbt.setenabled(true)
        self.recordbt.setenabled(true)
        self.grayimgckb.setenabled(true)
        if self.grayimgckb.ischecked() == 0:
            self.redcolorsld.setenabled(true)
            self.redcolorspb.setenabled(true)
            self.greencolorsld.setenabled(true)
            self.greencolorspb.setenabled(true)
            self.bluecolorsld.setenabled(true)
            self.bluecolorspb.setenabled(true)
        self.exptimesld.setenabled(true)
        self.exptimespb.setenabled(true)
        self.gainsld.setenabled(true)
        self.gainspb.setenabled(true)
        self.brightsld.setenabled(true)
        self.brightspb.setenabled(true)
        self.contrastsld.setenabled(true)
        self.contrastspb.setenabled(true)
        self.recordbt.settext('录像')

        self.timer.start(1)
        self.timelb=time.perf_counter()

    def stopcamera(self):
        if self.stopbt.text()=='暂停':
            self.stopbt.settext('继续')
            self.recordbt.settext('保存')
            self.timer.stop()
        elif self.stopbt.text()=='继续':
            self.stopbt.settext('暂停')
            self.recordbt.settext('录像')
            self.timer.start(1)

    def recordcamera(self):
        tag = self.recordbt.text()
        if tag == '保存':
            try:
                image_name=self.recordpath+'image'+time.strftime('%y%m%d%h%m%s',time.localtime(time.time()))+'.jpg'
                print(image_name)
                cv2.imwrite(image_name, self.image)
                self.msgte.clear()
                self.msgte.setplaintext('image saved.')
            except exception as e:
                self.msgte.clear()
                self.msgte.setplaintext(str(e))
        elif tag == '录像':
            self.recordbt.settext('停止')

            video_name = self.recordpath + 'video' + time.strftime('%y%m%d%h%m%s',time.localtime(time.time())) + '.avi'
            fps = self.fmratelcd.value()
            size = (self.image.shape[1],self.image.shape[0])
            fourcc = cv2.videowriter_fourcc('m', 'j', 'p', 'g')
            self.video_writer = cv2.videowriter(video_name, fourcc,self.camera.get(5), size)
            self.recordflag=1
            self.msgte.setplaintext('video recording...')
            self.stopbt.setenabled(false)
            self.exitbt.setenabled(false)
        elif tag == '停止':
            self.recordbt.settext('录像')
            self.video_writer.release()
            self.recordflag = 0
            self.msgte.setplaintext('video saved.')
            self.stopbt.setenabled(true)
            self.exitbt.setenabled(true)

    # 图像处理与显示
    def coloradjust(self, img):
        try:
            b = img[:, :, 0]
            g = img[:, :, 1]
            r = img[:, :, 2]

            # 根据滑动条的值进行颜色通道的调整
            b = b * self.b
            g = g * self.g
            r = r * self.r

            img_adjusted = img.copy()
            img_adjusted[:, :, 0] = b
            img_adjusted[:, :, 1] = g
            img_adjusted[:, :, 2] = r

            return img_adjusted
        except exception as e:
            self.msgte.setplaintext(str(e))

    def dispimg(self):
        if self.grayimgckb.ischecked():
            img = cv2.cvtcolor(self.image, cv2.color_bgr2gray)
        else:
            img = cv2.cvtcolor(self.image, cv2.color_bgr2rgb)
        qimg = qimage2ndarray.array2qimage(img)
        self.displb.setpixmap(qpixmap(qimg))
        self.displb.show()

    def timeroutfun(self):
        success, img = self.camera.read()
        if success:
            self.image = self.coloradjust(img)
            self.dispimg()
            self.image_num += 1
            if self.recordflag:
                self.video_writer.write(img)
            if self.image_num % 10 == 9:
                frame_rate = 10/(time.perf_counter()-self.timelb)
                self.fmratelcd.display(frame_rate)
                self.timelb = time.perf_counter()
                self.imgwidthlcd.display(self.camera.get(3))
                self.imgheightlcd.display(self.camera.get(4))
        else:
            self.msgte.clear()
            self.msgte.setplaintext('image obtaining failed.')

    def prepwidgets(self):
        self.prepcamera()
        self.stopbt.setenabled(false)
        self.recordbt.setenabled(false)
        self.grayimgckb.setenabled(false)
        self.redcolorsld.setenabled(false)
        self.redcolorspb.setenabled(false)
        self.greencolorsld.setenabled(false)
        self.greencolorspb.setenabled(false)
        self.bluecolorsld.setenabled(false)
        self.bluecolorspb.setenabled(false)
        self.exptimesld.setenabled(false)
        self.exptimespb.setenabled(false)
        self.gainsld.setenabled(false)
        self.gainspb.setenabled(false)
        self.brightsld.setenabled(false)
        self.brightspb.setenabled(false)
        self.contrastsld.setenabled(false)
        self.contrastspb.setenabled(false)

    def setr(self):
        r=self.redcolorsld.value()
        self.r=r/255

    def setg(self):
        g=self.greencolorsld.value()
        self.g=g/255

    def setb(self):
        b=self.bluecolorsld.value()
        self.b=b/255

    def setcontrast(self):
        contrast_toset=self.contrastsld.value()
        try:
            self.camera.set(11,contrast_toset)
            self.msgte.setplaintext('the contrast is set to ' + str(self.camera.get(11)))
        except exception as e:
            self.msgte.setplaintext(str(e))

    def setbrightness(self):
        brightness_toset=self.brightsld.value()
        try:
            self.camera.set(10,brightness_toset)
            self.msgte.setplaintext('the brightness is set to ' + str(self.camera.get(10)))
        except exception as e:
            self.msgte.setplaintext(str(e))

    def setgain(self):
        gain_toset=self.gainsld.value()
        try:
            self.camera.set(14,gain_toset)
            self.msgte.setplaintext('the gain is set to '+str(self.camera.get(14)))
        except exception as e:
            self.msgte.setplaintext(str(e))

    def setexposure(self):
        try:
            exposure_time_toset=self.exptimesld.value()
            self.camera.set(15,exposure_time_toset)
            self.msgte.setplaintext('the exposure time is set to '+str(self.camera.get(15)))
        except exception as e:
            self.msgte.setplaintext(str(e))

    def setgray(self):
        if self.grayimgckb.ischecked():
            self.redcolorsld.setenabled(false)
            self.redcolorspb.setenabled(false)
            self.greencolorsld.setenabled(false)
            self.greencolorspb.setenabled(false)
            self.bluecolorsld.setenabled(false)
            self.bluecolorspb.setenabled(false)
        else:
            self.redcolorsld.setenabled(true)
            self.redcolorspb.setenabled(true)
            self.greencolorsld.setenabled(true)
            self.greencolorspb.setenabled(true)
            self.bluecolorsld.setenabled(true)
            self.bluecolorspb.setenabled(true)

    def setfilepath(self):
        dirname = qfiledialog.getexistingdirectory(self, "浏览", '.')
        if dirname:
            self.filepathle.settext(dirname)
            self.recordpath=dirname+'/'

    def callbackfunctions(self):
        self.filepathbt.clicked.connect(self.setfilepath)
        self.showbt.clicked.connect(self.startcamera)
        self.stopbt.clicked.connect(self.stopcamera)
        self.recordbt.clicked.connect(self.recordcamera)
        self.exitbt.clicked.connect(self.exitapp)
        self.grayimgckb.statechanged.connect(self.setgray)
        self.exptimesld.valuechanged.connect(self.setexposure)
        self.gainsld.valuechanged.connect(self.setgain)
        self.brightsld.valuechanged.connect(self.setbrightness)
        self.contrastsld.valuechanged.connect(self.setcontrast)
        self.redcolorsld.valuechanged.connect(self.setr)
        self.greencolorsld.valuechanged.connect(self.setg)
        self.bluecolorsld.valuechanged.connect(self.setb)

    def exitapp(self):
        self.timer.stop()
        self.camera.release()
        self.msgte.setplaintext('exiting the application..')
        qcoreapplication.quit()

if __name__ == '__main__':
    app = qapplication(sys.argv)
    ui=camshow()
    ui.show()
    sys.exit(app.exec_())

 

 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com