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

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_Hmainwindow.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_Himgplayer.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);
}目录 返回
首页