在更新期间显示图像(如演示文稿)而不显示桌面

Posted

技术标签:

【中文标题】在更新期间显示图像(如演示文稿)而不显示桌面【英文标题】:Displaying images like a presentation without showing the desktop during update 【发布时间】:2017-02-13 09:30:18 【问题描述】:

我正在尝试使用 Xubuntu 14.04 下的以下 Python 代码在我的辅助显示器上连续显示存储在 ./pics 目录下的图像。

from PyQt4 import QtCore, QtGui
import sys
import os
import multiprocessing as mp
import time

def displayImage( impath ):

    app = QtGui.QApplication(sys.argv)
    window = QtGui.QMainWindow()

    # Select monitor
    screenres = QtGui.QApplication.desktop().screenGeometry(1);
    window.move(QtCore.QPoint(screenres.x(), screenres.y()))
    window.resize(screenres.width(), screenres.height())

    # Set the image to be shown
    pic = QtGui.QLabel(window)
    pic.setGeometry(0, 0, 1960, 1080)
    pic.setPixmap(QtGui.QPixmap( impath ))

    window.showFullScreen()
    app.exec_()

    return

def controller( imdir ):

    # List the contents of the directory
    im_paths = os.listdir( imdir )

    # Keep only image files 
    pc = list(im_paths)
    for p in pc:
        print p
        if not p.split('.')[-1] in [ 'jpg', 'JPG', 'png', 'PNG' ]:
            im_paths.remove( p )

    if not im_paths:
        return 1

    # Start showing the images by calling project function as a new process (multiprocessing module)
    for f in im_paths:

        print 'Showing image:', p, '...'

        # Run project process
        p = mp.Process( target=displayImage, args=( imdir+f, ) )
        p.start()

        # Keep dispaying image for 3 seconds 
        time.sleep(2)

        p.terminate()

    return 0

if __name__ == '__main__':

    controller( './pics/' )
    exit(0)

问题

显示图像A的进程终止有一段时间,直到进程结束 显示图像 B 出现在应用程序不显示任何内容的地方,并且有一段时间呈现桌面破坏了用户体验。

任何想法如何使用 Qt4 连续显示图像?

附言。可能会接受涉及 matplotlib 和/或 opencv 的答案,但我认为直接的路径是通过 Qt。

【问题讨论】:

只是一个问题:为什么要为显示的每张图像启动一个新的 QApplication,而不是只启动一个而不只是更新Pixmap 中的图像?正确初始化需要时间。然后当你已经显示一个图像时,创建一个新的QPixmap 并在x 秒后使用QPixmap.swap 切换? 嗨!我对 Qt 没有经验,所以我无法想象最佳解决方案是什么。你的回答似乎是个好主意!所以,我正在努力。您能否提供一个使用 QPixmap.swap 方法的示例? 【参考方案1】:

最后,我想出了解决方案。 alexblae 认为不应在每次图像更新时重新启动 qt 应用程序的想法是关键点。但首先...我必须详细了解 Qt 框架的体系结构,一个类如何从另一个类继承以及如何生成和处理事件。

让我引用更新后的代码,以便其他用户在遇到类似问题时查看并获得优势。

from PyQt4 import QtCore, QtGui
import multiprocessing as mp
import sys
import os
import time

class Pic( QtGui.QLabel ):
    def __init__( self, w, im_paths ):
        QtGui.QLabel.__init__(self,w)
        self.ims = im_paths
        # Set the first image that will be displayed
        self.setPixmap(QtGui.QPixmap( self.ims[0] ) )
        self.i = 1

    # Catch timer events. On each event display the next image
    def timerEvent(self):     
        # Update the displayed image    
        self.setPixmap(QtGui.QPixmap( self.ims[self.i] ) )
        self.i = ( self.i + 1 ) % len( self.ims )

def displayImages( im_paths ):

    app = QtGui.QApplication(sys.argv)

    window = QtGui.QMainWindow()

    screenres = QtGui.QApplication.desktop().screenGeometry(1);
    window.move(QtCore.QPoint(screenres.x(), screenres.y()))
    window.resize(screenres.width(), screenres.height())

    pic = Pic(window, im_paths)
    pic.setGeometry(0, 0, 1960, 1080)

    window.showFullScreen()

    # Generate a timerEvent every 1 second. On each second the handler of
    # the event updates the displayed image
    timer = QtCore.QTimer()
    timer.timeout.connect(pic.timerEvent)
    timer.start(1000)   #1 second

    sys.exit(app.exec_())

def controller( imdir ):

    # List the contents of the directory
    im_paths = sorted( os.listdir( imdir ) )

    for i, path in enumerate( im_paths ):
        im_paths[i] = imdir + '/' + path

    # Keep only image files 
    pc = list(im_paths)
    for p in pc:
        if not p.split('.')[-1] in [ 'jpg', 'JPG', 'png', 'PNG' ]:
            im_paths.remove( p )

    if not im_paths:
        return 1

    # Run project process
    p = mp.Process( target=displayImages, args=( im_paths, ) )
    p.start()

    # Keep displaying images for 1 minute
    time.sleep(5)
    p.terminate()

    return 0

if __name__ == '__main__':

    controller( './pics/' )
    exit(0)

Pic 类继承自 QLabel,以便定义 timerEvent 方法。使用计时器事件,我们能够通知 qt 应用程序何时更新显示的图像。

另外,请注意,多处理模块的使用似乎有点矫枉过正。有人可能会直接调用 displayImages 函数。

【讨论】:

这是特定于 Linux 系统的吗? 不,代码可以在Linux和Windows系统上执行。唯一的依赖是 Qt 框架。【参考方案2】:

我有一个使用 OpenCV 和 python 的解决方案。

下面是代码和解释:

import cv2    # for read/display images
import glob   # for linking to image file (.jpg)

#--- following is the directory containing my images of jpg format ---
jpg_files=glob.glob("C:/Users/Desktop/Stack/*.jpg")

#--- Here I run through every image file, read it and then display it with a lapse time of 1 second ---
for img_no in range(len(jpg_files)):  
    x = jpg_files[img_no]    
    img = cv2.imread(x,1)
    cv2.imshow('BINGO.jpg',img)
    cv2.waitKey(1000)

cv2.destroyAllWindows()

希望这会有所帮助 :D

【讨论】:

嗨耶鲁!感谢你付出的努力!由于缺乏特定要求,该解决方案不太适合,该解决方案应涵盖:a) 没有窗口装饰器的全屏模式和 b) 选择特定显示器的能力。 嗯,很高兴我能提供一些见解。请检查cv2.namedWindow() 的功能。它可能会有所帮助。 如果遇到一个解决方案,请发布:) 刚刚添加了解决方案。

以上是关于在更新期间显示图像(如演示文稿)而不显示桌面的主要内容,如果未能解决你的问题,请参考以下文章

Xaringan 演示文稿的演示者模式不同步

如何让Pages文稿显示字数统计?

iOS:如何在静态图像上添加动态按钮?

ppt打不开,显示发现文件中的内容有问题。可尝试修复此演示文稿

为啥用qq邮箱给别人发演示文稿时图片和汉字会分开有的图片还会重叠有的汉字看不到

检测水平和垂直边缘opencv