图片轮播应用_imgShow

09 11月
作者:cinjep|分类:代码开源

一个用于图片轮播的工具,支持自定义图片播放时间,开始和结束播放时间(不在播放时间范围内黑屏),开始播放后屏蔽除了ESC以外的常用按键。写该小应用是为了简化LED大屏播放图片的操作。

pic.PNG

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QTime>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void dragEnterEvent(QDragEnterEvent*event) Q_DECL_OVERRIDE;
    void dropEvent(QDropEvent *event) Q_DECL_OVERRIDE;

    void readConfigIni();


private slots:
    void onAddImg();
    void onCustomContextMenuRequested(const QPoint &);
    void onDelItem();
    void itemUp();
    void itemDown();

    void saveConfigIni();

    void startPlay();
protected:


private:
    Ui::MainWindow *ui;
    QString duration;

    QTime startTime;
    QTime endTime;



};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QFileDialog>
#include <QDebug>
#include <QMenu>
#include <QPoint>
#include <QListWidget>
#include <QDropEvent>
#include <QMimeData>
#include <QPainter>
#include <QSettings>
#include <QTextCodec>
#include <QStandardPaths>
#include <QList>
#include <QTime>

#include "imgplayer.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    this->setWindowFlags(Qt::Window | Qt::WindowTitleHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);

    ui->imgListWidget->setDragDropMode(QAbstractItemView::InternalMove);
    ui->imgListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

    this->readConfigIni();
    QObject::connect(ui->addImgBtn,SIGNAL(clicked(bool)),this,SLOT(onAddImg()));
    QObject::connect(ui->saveBtn,SIGNAL(clicked(bool)),this,SLOT(saveConfigIni()));
    QObject::connect(ui->imgListWidget,SIGNAL(customContextMenuRequested(const QPoint &)),this,SLOT(onCustomContextMenuRequested(const QPoint &)));
    this->setAcceptDrops(true); //必须设置,不然无法接收拖放事件
    ui->imgListWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    QObject::connect(ui->startBtn,SIGNAL(clicked(bool)),this,SLOT(startPlay()));

    //ui->durationSpinBox->setFocusPolicy(Qt::NoFocus);

}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::onAddImg()
{
    QStringList FileNames = QFileDialog::getOpenFileNames(this, QStringLiteral("选择图片文件!"), QStandardPaths::writableLocation(QStandardPaths::PicturesLocation),QStringLiteral("图片文件(*.png *.jpg *.bmp)"));
    int index=0,count=0;
    count = FileNames.count();
    for(index=0;index<=count-1;index++)
    {
        QListWidgetItem *item = new QListWidgetItem;
        item->setSizeHint(QSize(0,24));
        item->setText(QFileInfo(FileNames.at(index)).absoluteFilePath());
        QString suf = QFileInfo(FileNames.at(index)).suffix();
        ui->imgListWidget->addItem(item);
    }
    int itemCount = ui->imgListWidget->count();
    ui->countLabel->setText("图片数:" + QString::number(itemCount));
    itemCount>0?ui->startBtn->setEnabled(true):ui->startBtn->setEnabled(false);
}


//图片项右键
void MainWindow::onCustomContextMenuRequested(const QPoint &pos)
{
    QListWidgetItem* curItem = ui->imgListWidget->itemAt(pos);
    if( curItem == NULL )
        return;
    QMenu *popMenu = new QMenu(ui->imgListWidget);
    QAction *Menu1 = new QAction("上移");
    QAction *Menu2 = new QAction("下移");
    QAction *Menu3 = new QAction("删除");
    popMenu->addAction(Menu1);
    popMenu->addAction(Menu2);
    popMenu->addAction(Menu3);
    connect(Menu1, SIGNAL(triggered(bool)), this, SLOT(itemUp()));
    connect(Menu2, SIGNAL(triggered(bool)), this, SLOT(itemDown()));
    connect(Menu3, SIGNAL(triggered(bool)), this, SLOT(onDelItem()));
    popMenu->exec( QCursor::pos());
}

//删除选中
void MainWindow::onDelItem()
{
    QList<QListWidgetItem*> list = ui->imgListWidget->selectedItems();
    if(list.size() == 0)
        return;
    for(int i=0;i<list.count();i++){
        QListWidgetItem *sel = list[i];
        if(sel){
            ui->imgListWidget->removeItemWidget(sel);
            delete sel;
        }
    }
    int itemCount = ui->imgListWidget->count();
    ui->countLabel->setText("图片数:" + QString::number(itemCount));
    itemCount>0?ui->startBtn->setEnabled(true):ui->startBtn->setEnabled(false);
}

void MainWindow::itemUp()
{
    QList<QListWidgetItem*> list = ui->imgListWidget->selectedItems();
    if(list.size() == 0)
        return;
    for(int i=0;i<list.count();i++){
        QListWidgetItem *sel = list[i];
        if (sel)
        {
            ui->imgListWidget->setCurrentItem(sel);
            int currentRow = ui->imgListWidget->currentRow();
            if (currentRow == -1)
                return;
            int arriveRow = currentRow - 1 < 0 ? 0 : currentRow - 1;
            ui->imgListWidget->insertItem(std::min(currentRow, arriveRow), ui->imgListWidget->takeItem(std::max(currentRow, arriveRow)));
            ui->imgListWidget->setCurrentRow(arriveRow);
        }
    }
    ui->imgListWidget->setCurrentItem(NULL);
}

void MainWindow::itemDown()
{
    QList<QListWidgetItem*> list = ui->imgListWidget->selectedItems();
    if(list.size() == 0)
        return;
    for(int i=0;i<list.count();i++){
        QListWidgetItem *sel = list[i];
        if (sel)
        {
            ui->imgListWidget->setCurrentItem(sel);
            int currentRow = ui->imgListWidget->currentRow();
            if (currentRow == -1)
                return;
            int arriveRow = currentRow + 1 >= ui->imgListWidget->count() ? ui->imgListWidget->count() - 1 : currentRow + 1;
            ui->imgListWidget->insertItem(std::min(currentRow, arriveRow), ui->imgListWidget->takeItem(std::max(currentRow, arriveRow)));
            ui->imgListWidget->setCurrentRow(arriveRow);
        }
    }
    ui->imgListWidget->setCurrentItem(NULL);
}


//拖动文件到窗口,触发
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    if(event->mimeData()->hasUrls())
    {
        event->acceptProposedAction(); //事件数据中存在路径,方向事件
    }
    else
    {
        event->ignore();
    }
}


//拖动文件到窗口释放文件,触发
void MainWindow::dropEvent(QDropEvent *event)
{
    const QMimeData *mimeData = event->mimeData();
    if(mimeData->hasUrls())
    {
        QList<QUrl> urls = mimeData->urls();
        for(int i=0;i<urls.count();i++)
        {
            QListWidgetItem *item = new QListWidgetItem;
            item->setSizeHint(QSize(0,24));
            QString fileName = urls.at(i).toLocalFile();
            QFileInfo fileinfo = QFileInfo(fileName);
            item->setText(fileName);
            QString suf = fileinfo.suffix();
            if(suf == "jpg" || suf == "JPG")
            {
                ui->imgListWidget->addItem(item);
                item->setData(Qt::UserRole,fileName);
            }
            if(suf == "png" || suf == "PNG")
            {
                ui->imgListWidget->addItem(item);
                item->setData(Qt::UserRole,fileName);
            }
            if(suf == "bmp" || suf=="BMP")
            {
                ui->imgListWidget->addItem(item);
                item->setData(Qt::UserRole,fileName);
            }
        }
    }
    int itemCount = ui->imgListWidget->count();
    ui->countLabel->setText("图片数:" + QString::number(itemCount));
    itemCount>0?ui->startBtn->setEnabled(true):ui->startBtn->setEnabled(false);
}


void MainWindow::readConfigIni(){
    QString fullFileName= QDir::currentPath()+"/playconfig.ini";
    QFileInfo fileInfo(fullFileName);
    if(fileInfo.isFile()){
        QSettings *configIni = new QSettings(fullFileName, QSettings::IniFormat);
        configIni->setIniCodec(QTextCodec::codecForName("UTF_8")); //解决读取Ini文件中中文乱码的情况
        configIni->beginGroup("config");

        duration = configIni->value("duration").toString();
        ui->durationSpinBox->setValue(duration.toInt());

        QString startTime = configIni->value("starttime").toString();
        ui->startTimeTxt->setTime(QTime::fromString(startTime,"HH:mm:ss"));

        QString endTime = configIni->value("endtime").toString();
        ui->endTimeTxt->setTime(QTime::fromString(endTime,"HH:mm:ss"));

        configIni->endGroup();
        configIni->beginGroup("imgList");
        QStringList groupKeys = configIni->allKeys();
        for (const QString &key : groupKeys) {
            QString value = configIni->value(key).toString();
            QListWidgetItem *item = new QListWidgetItem;
            item->setText(value);
            ui->imgListWidget->addItem(item);
        }
        configIni->endGroup();
        int itemCount = ui->imgListWidget->count();
        ui->countLabel->setText("图片数:" + QString::number(itemCount));
    }
    else{
        ui->infoLabel->setText("配置文件读取失败 ");
    }
}

void MainWindow::saveConfigIni(){
    startTime = ui->startTimeTxt->time();
    endTime = ui->endTimeTxt->time();
    if(endTime<startTime){
        ui->infoLabel->setText("<font color='#ff0000'>时间不正确,配置文件保存失败 </font>");
        return;
    }

    QString fullFileName= QDir::currentPath()+"/playconfig.ini";
    QFileInfo fileInfo(fullFileName);
    if(fileInfo.isFile() && endTime>startTime){
        QSettings *configIni = new QSettings(fullFileName, QSettings::IniFormat);
        configIni->beginGroup("config");
        configIni->setValue("duration",ui->durationSpinBox->value());
        configIni->setValue("starttime",ui->startTimeTxt->time().toString());
        configIni->setValue("endtime",ui->endTimeTxt->time().toString());
        configIni->endGroup();

        configIni->beginGroup("imgList");
        QString  imgKey;
        if(ui->imgListWidget->count()==0){
            configIni->clear();
        }
        else{
            for(int i=0; i<ui->imgListWidget->count();i++){
                imgKey = QString("img%1").arg(i);
                configIni->setValue(imgKey,ui->imgListWidget->item(i)->text());
            }
        }
        configIni->endGroup();
        ui->infoLabel->setText("配置文件保存完毕 ");
    }
    else{
        ui->infoLabel->setText("<font color='#ff0000'>配置文件保存失败 </font>");
    }
}

void MainWindow::startPlay(){
    QStringList imgList;
    int duration = (ui->durationSpinBox->value())*1000;
    int imgCount = ui->imgListWidget->count();

    startTime = ui->startTimeTxt->time();
    endTime = ui->endTimeTxt->time();
    if(endTime<startTime){
        ui->infoLabel->setText("<font color='#ff0000'>时间不正确,无法开始!</font>");
        return;
    }

    if(imgCount>0 && endTime>startTime){
        for(int i=0; i<imgCount;i++){
            imgList.append(ui->imgListWidget->item(i)->text());
        }
        imgPlayer *mp = new imgPlayer(imgList, duration, startTime, endTime);
        mp->show();
        this->setWindowState(Qt::WindowMinimized);
        ui->infoLabel->setText("");
    }
}



imgplayer.h

#ifndef IMGPLAYER_H
#define IMGPLAYER_H

#include <QWidget>
#include <QTimer>

#include <QPixmap>
#include <QSystemTrayIcon>
#include <QDateTime>

#include <windows.h>

namespace Ui {
class imgPlayer;
}

class imgPlayer : public QWidget
{
    Q_OBJECT

public:
    explicit imgPlayer(const QStringList &m_imgList, const int &m_duration, const QTime &m_startTime, const QTime &m_endTime, QWidget *parent = nullptr);
    ~imgPlayer();

protected:
    void keyPressEvent(QKeyEvent *event) override;
    void enterEvent(QEvent *event) override;
    void cleanup();

private slots:
    void nextImage();
    void checkTask();

private:
    Ui::imgPlayer *ui;
    QTimer *imageTimer;
    QTimer *checkTimer;
    int duration;
    QPixmap pixmap;
    QStringList imgPathList;
    int currentImageIndex;
    QTime startTime;
    QTime endTime;

    bool taskFlag;
    bool runOnce;

    QDateTime now;

    static HHOOK hKeyboardHook;
    static LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);

};

#endif // IMGPLAYER_H


imgplayer.cpp

#include "imgplayer.h"
#include "ui_imgplayer.h"

#include <QFileInfo>
#include <QSettings>
#include <QDir>
#include <QTextCodec>
#include <QPixmap>
#include <QDebug>
#include <QKeyEvent>
#include <QCursor>
#include <QDateTime>
#include <QTime>

HHOOK imgPlayer::hKeyboardHook = nullptr;

imgPlayer::imgPlayer(const QStringList &m_imgList, const int &m_duration, const QTime &m_startTime, const QTime &m_endTime, QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::imgPlayer)
{

    // 安装低级键盘钩子
    hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(nullptr), 0);
    if (!hKeyboardHook) {
        return;
    }

    ui->setupUi(this);
    this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
    this->showFullScreen();

    ui->imgLabel->setText("等待播放中...");
    ui->imgLabel->setAlignment(Qt::AlignCenter);
    this->imgPathList = m_imgList;
    this->duration = m_duration;
    this->startTime = m_startTime;
    this->endTime = m_endTime;

    currentImageIndex = 0;
    taskFlag = false;
    runOnce = true;


    checkTimer = new QTimer(this);
    connect(checkTimer,&QTimer::timeout,this,&imgPlayer::checkTask);
    checkTimer->start(1000);

    imageTimer = new QTimer(this);
    connect(imageTimer,&QTimer::timeout,this,&imgPlayer::nextImage);
    imageTimer->start(duration);
}

imgPlayer::~imgPlayer()
{
    if (hKeyboardHook) {
        UnhookWindowsHookEx(hKeyboardHook);
    }
    cleanup();
    delete ui;
}

void imgPlayer::checkTask(){
    now = QDateTime::currentDateTime();
    if (now.time() >= startTime && now.time() < endTime){
        taskFlag = true;
        if(runOnce){
            currentImageIndex = 0;
            pixmap.load(imgPathList[currentImageIndex]);
            //ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
            ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
            ui->imgLabel->show();
            runOnce =false;
        }
    }
    else{
        taskFlag = false;
    }
}

void imgPlayer::nextImage()
{
    if (taskFlag){
        if(currentImageIndex >=imgPathList.size()){
            currentImageIndex = 0;
        }
        currentImageIndex = (currentImageIndex + 1) % imgPathList.size(); // 循环显示图片
        pixmap.load(imgPathList[currentImageIndex]);
        //ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::KeepAspectRatio,Qt::SmoothTransformation));
        ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
        ui->imgLabel->show();
    }
    else{
        pixmap.load(":/black.png");
        //ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::KeepAspectRatio,Qt::FastTransformation));
        ui->imgLabel->setPixmap(pixmap.scaled(ui->imgLabel->size(),Qt::IgnoreAspectRatio,Qt::SmoothTransformation));
        ui->imgLabel->show();
    }
}

void imgPlayer::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Escape) {
        cleanup();
        this->close();
    }
}

void imgPlayer::cleanup()
{
    if (imageTimer) {
        imageTimer->stop();
        delete imageTimer;
        imageTimer = nullptr;
    }
    if (checkTimer) {
        checkTimer->stop();
        delete checkTimer;
        checkTimer = nullptr;
    }
}


void imgPlayer::enterEvent(QEvent *event) {
    if (event->type() == QEvent::Enter) {
        QCursor cursor(Qt::BlankCursor); // 创建一个透明的光标
        setCursor(cursor); // 将光标设置为当前窗口
    }
}


LRESULT CALLBACK imgPlayer::LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode == HC_ACTION) {
        KBDLLHOOKSTRUCT *pKeyInfo = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);

        // 拦截以下按键组合:
        bool isAltTab = pKeyInfo->vkCode == VK_TAB && (GetAsyncKeyState(VK_MENU) & 0x8000);
        bool isWinKey = pKeyInfo->vkCode == VK_LWIN || pKeyInfo->vkCode == VK_RWIN;
        bool isAltEsc = pKeyInfo->vkCode == VK_ESCAPE && (GetAsyncKeyState(VK_MENU) & 0x8000);
        bool isCtrlEsc = pKeyInfo->vkCode == VK_ESCAPE && (GetAsyncKeyState(VK_CONTROL) & 0x8000);

        bool isAltF4 = pKeyInfo->vkCode == VK_F4 && (GetAsyncKeyState(VK_MENU) & 0x8000);

        // 根据需要添加其他热键检测
        if (isAltTab || isWinKey || isAltEsc || isCtrlEsc || isAltF4) {
            return 1; // 拦截该事件
        }
    }
    // 传递其他事件
    return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}


 imgShow下载

浏览163
返回
目录
返回
首页
Qt C++中生成验证码 LNMP环境搭建