原始战争之主界面滑动效果

简介:在弄一个横版的游戏,需要一个随鼠标左右滑动的功能,最终做了一个拖动的效果。

  • 鼠标左右移动界面也滑动

    • 实际做的时候,搜了一下没有滑动的方案,那就假想游戏界面长度大于窗口界面(类比给卷轴加游标),然后根据鼠标左右移动事件,去计算卷轴应该在的位置,然后更新界面。如果左右移动处理麻烦(滚动速度太快或太慢,现在如果玩红警95就存在鼠标移动速度问题),也可以在血条中间加上一个滑动条,来精确的控制位置。

打算用图片来模拟卷轴大小

来用一个光头的图片来模拟的时候,发现一个问题:

QLabel设置大小无效问题

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFrame
from PyQt5.QtCore import QSize
from PyQt5.QtGui import QPixmap

class War(QMainWindow):
    ‘‘‘游戏主类‘‘‘
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.board = Scroll(self)

        # 窗口设置
        self.setFixedSize(QSize(720,480))
        self.setWindowTitle("原始战争")
        self.show()

class Scroll(QFrame):
    ‘‘‘卷轴测试类‘‘‘
    def __init__(self, parent):
        super().__init__(parent)

        self.lbl = QLabel(self)
        self.qpix=QPixmap(sys.path[0]+‘/resource/57001_one_punch_man.jpg‘)
        self.lbl.setGeometry(0,0,720,480)
        self.lbl.setPixmap(self.qpix)

if __name__ == ‘__main__‘:
    app = QApplication([])
    war = War()
    sys.exit(app.exec_())

看效果

发现图片没有显示出来,只显示在了左上角,其实不是QPixmap的问题,时QLabel大小设置的问题。如果把

self.lbl = QLabel(self)
self.qpix=QPixmap(sys.path[0]+‘/resource/57001_one_punch_man.jpg‘)
self.lbl.setGeometry(0,0,720,480)
self.lbl.setPixmap(self.qpix)

这段代码放到War类的initUI()方法下直接调用的话,是可以的,所以问题出在了其他类中的QLable下,初始化QLabel时我用的是self,试着用了下parent就好了。

self.lbl = QLabel(parent)

原因是

QLabel::QLabel(QWidget *parent = nullptr, Qt::WindowFlags f = ...)

第一个参数为父级QWidget对象。 Qt Documentation - QLabel Class

这个问题是个小插曲,继续做滑动效果,为了方便测试还是在一个类做尝试。

尝试用鼠标移动触发

首先选择了好久最后打算用QScrollArea来处理

先将滚动条加上

def initUI(self):

        self.lbl = QLabel(self)
        self.qpix=QPixmap(sys.path[0]+‘/resource/57001_one_punch_man.jpg‘).scaledToHeight(480)
        self.lbl.setGeometry(self.qpix.rect())
        self.lbl.setPixmap(self.qpix)

        # 添加滚动条,并添加组件
        scrollArea = QScrollArea(self)
        scrollArea.setWidget(self.lbl)
        scrollArea.resize(QSize(720,480))

        # 窗口设置
        self.resize(QSize(720,480))
        self.setWindowTitle("原始战争")

self.qpix=QPixmap(sys.path[0]+‘/resource/57001_one_punch_man.jpg‘).scaledToHeight(480)

先把图定高等比例缩放。再添加滚动条。

效果:

搞定,鼠标拖动

鼠标拖动也刚好解决了滑动烦人的速度问题,此处功能以后还可以做RTS用。

在一个论坛看到一篇用C++写的拖动例子,关键在于重载滚动条的事件过滤

bool eventFilter(QObject *o, QEvent *e)
{
    if(o!=l)
        return QScrollArea::eventFilter(o,e);
    if(e->type()==QEvent::MouseButtonPress)
    {
        m_prev = ((QMouseEvent*)e)->pos();
        this->prev_diff.setX(0);
        this->prev_diff.setY(0);
        return true;
    }
    if(e->type()==QEvent::MouseMove)
    {
        QPoint pt = ((QMouseEvent*)e)->pos();
        this->diff = pt-m_prev-prev_diff*n;
        m_prev = pt;
        horizontalScrollBar()->setValue(horizontalScrollBar()->value()+diff.x()*n);
        verticalScrollBar()->setValue(verticalScrollBar()->value()+diff.y()*n);
        qDebug()<<"("+QString::number(diff.x())+","+QString::number(diff.y())+")";
        this->prev_diff=diff;
        return true;
    }
    return QScrollArea::eventFilter(o,e);
}

改了一下:

import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QFrame, QScrollArea, QWidget, QVBoxLayout, QHBoxLayout, QScrollBar, QAbstractScrollArea
from PyQt5.QtCore import QSize, Qt, QEvent, QPoint
from PyQt5.QtGui import QPixmap

class War(QMainWindow):
    ‘‘‘游戏主类‘‘‘
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):

        self.lbl = QLabel(self)
        self.qpix=QPixmap(sys.path[0]+‘/resource/57001_one_punch_man.jpg‘).scaledToHeight(480)
        self.lbl.setGeometry(self.qpix.rect())
        self.lbl.setPixmap(self.qpix)
        print(self.lbl)
        # 添加滚动条,并添加组件
        scrollArea = ScrollArea(self)
        scrollArea.setWidgetResizable(True)
        #scrollArea.setBackgroundRole(QPalette::Dark);
        scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 隐藏滚动条
        scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        scrollArea.setWidget(self.lbl)
        scrollArea.resize(QSize(720,480))

        # 窗口设置
        self.resize(QSize(720,480))
        self.setWindowTitle("原始战争")

        #self.scroll(400,200)
        #self.update()

class ScrollArea(QScrollArea):
    ‘‘‘重载滚动条类‘‘‘
    def __init__(self, parent):
        super().__init__(parent)

        self.n=0.8
        self.m_prev = QPoint()
        self.diff = QPoint()
        self.prev_diff = QPoint(0, 0)
        self.widget = None

    def setWidget(self, w):
        ‘‘‘设置区域部件时,对象赋值‘‘‘
        super().setWidget(w)
        self.widget=w
        self.widget.installEventFilter(self)

    def eventFilter(self,obj,evt):
        ‘‘‘事件过滤‘‘‘
        #print(QScrollArea.widget(self),obj)
        if(obj!=self.widget):
            return super().eventFilter(obj,evt)

        if(evt.type()==QEvent.MouseButtonPress):
            self.m_prev = evt.pos()
            self.prev_diff.setX(0)
            self.prev_diff.setY(0)

        # 鼠标移动
        # MouseMove为鼠标拖动效果,鼠标滑动是ToolTip
        if(evt.type()==QEvent.MouseMove):
            #print(evt.pos())
            pt = evt.pos()
            self.diff = pt-self.m_prev-self.prev_diff*self.n
            self.diff = -1*self.diff
            print(‘diff x :‘,self.diff.x())
            self.m_prev = pt

            print(self.horizontalScrollBar().value()+self.diff.x()*self.n,‘--‘)
            self.horizontalScrollBar().setValue(self.horizontalScrollBar().value()+self.diff.x()*self.n)
            # horizontalScrollBar().setValue(horizontalScrollBar().value()+self.diff.x()*self.n);
            # verticalScrollBar()->setValue(verticalScrollBar()->value()+diff.y()*n); # 竖向暂时不需要移动
            self.prev_diff=self.diff;
            return True
        return QScrollArea.eventFilter(self,obj, evt)

if __name__ == ‘__main__‘:
    app = QApplication([])
    war = War()
    war.show()
    sys.exit(app.exec_())

github

最终界面效果:

总结

QT做的太好了,看C++文档和代码,一般理解了都可以无缝用PY重写。

以为俩小时能搞好的,搞了一天。英语还是很重要,就是没动力学 嗝。

最佳实践就是动手去做,在实战中学习、成长,而不是等所有的都准备好之后再开始。这两天园子首页的推荐彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践

参考,致谢

原文地址:https://www.cnblogs.com/warcraft/p/9464100.html

时间: 2024-08-10 08:14:54

原始战争之主界面滑动效果的相关文章

Android ViewPager和Fragment实现顶部导航界面滑动效果

在项目中,我们常常需要实现界面滑动切换的效果.例如,微信界面的左右滑动切换效果.那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果. 一. ViewPager 官方API 首先我们来看一下ViewPager官方给出的解释,如图: 具体意思如下: Layout 管理器允许用户可以在页面上,左右滑动来翻动页面.你可以考虑实现PagerAdapter接口来显示该效果. ViewPager很多时候会结合Fragment一块使用,这种方法使得管理每个页面的生命周期变得

ViewPager和Fragment结合使用,可以做出顶部导航界面滑动效果

在项目中,我们常常需要实现界面滑动切换的效果.例如,微信界面的左右滑动切换效果.那这种效果是怎么实现的?今天我就带大家简单了解ViewPager,并通过实例来实现该效果. 一. ViewPager 官方API 首先我们来看一下ViewPager官方给出的解释,如图: 具体意思如下: Layout 管理器允许用户可以在页面上,左右滑动来翻动页面.你可以考虑实现PagerAdapter接口来显示该效果. ViewPager很多时候会结合Fragment一块使用,这种方法使得管理每个页面的生命周期变得

ScrollView + viewpager实现android的app主界面效果

ScrollView + viewpager实现android的app主界面效果 Android的主界面一般由两部分组成:导航栏,滑动的分屏(我自己这么叫的).其中滑动的分屏肯定是用的fragment,具体的承载的控件是viewpager.而导航分页栏用的控件就有很多了,tabhost,Scrollview或者自定义的都行. 个人认为tabhost和Scrollview都是比较好的,因为后期的可拓展性比较好,除非导航栏界面确实属于"自定义"范畴,基本上我们可以选择这两样就可以了. 其实

高仿美团主界面&lt;一&gt;

声明:本demo还未完善,正在持续更新中... 先上图吧: 这个小demo资源图片全是用青花瓷抠出来的,现在只是完成了 一部分.会持续更行中...有兴趣的朋友可以关注我,我们一起coding,一起分享. 然后这个demo很简单.但是有一些小细节可以和大家分享. 相信用过美团的同鞋都知道,美团的主界面. 效果动画图如下: git图 很明显美团的主界面是一个tableView 如上图的scrollView是tableView的一个cell. 快速创建一个cell并传递一个模型. (UITableVi

(NO.00004)iOS实现打砖块游戏(二):实现游戏主界面动画

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 一个内容不错的游戏也要一个好的包装.玩家进入游戏时第一眼看到的是将是游戏的主界面,如何生动的展示一个具有吸引力的界面就是本篇的主题.当然这里无法和商业游戏的主界面相比的,只是展示一下不用写什么代码,也可以把主界面做的比较活泼. 在主界面上添加静态元素 打开SpriteBuilder中的MainScene.ccb文件,将原有控件统统删掉,这时场景变得黑漆漆的一片.

iOS开发之主界面的左右滑动

前言:可能很多iOS开发者在学习之初都会对QQ的主界面的左滑与右滑动感到好奇,今天开始写我人生中的第一篇博客,即:iOS开发之Slide(主界面侧滑侧边栏). 正文: 首先,新建类(HomeViewController:命名随自己)继承ViewController. 然后我们需要声明这些属性: //滑动速度系数-建议在0.5-1之间.默认为0.5 @property (nonatomic, assign) CGFloat speedf; //左侧窗控制器 @property (nonatomic

android仿系统Launcher界面,实现分屏,左右滑动效果(ViewSwitcher)

ViewSwitcher代表了视图切换组件, 本身继承了FrameLayout ,可以将多个View叠在一起 ,每次只显示一个组件.当程序控制从一个View切换到另个View时,ViewSwitcher 支持指定动画效果. 为了给ViewSwitcher 添加多个组件, 一般通过ViewSwitcher 的setFactory 方法为止设置ViewFactory ,并由ViewFactory为之创建View 即可. 下面通过一个实例来介绍 ViewSwitcher的用法.(仿Android系统L

WPF技术触屏上的应用系列(六): 视觉冲击、超炫系统主界面、系统入口效果实现

原文:WPF技术触屏上的应用系列(六): 视觉冲击.超炫系统主界面.系统入口效果实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系统,54寸大屏电脑电视一体机.要求有很炫的展示效果,要有一定的视觉冲击力,可触控操作.当然满足客户的要求也可以有其它途径.但鉴于咱是搞 .NET技术的,首先其冲想到的微软WPF方面,之前对WPF的了解与学习也只是停留在比较浅的层面,没有进一步深入学习与应用.所以在项目接来以后,也就赶鸭子上架了,经过努力奋斗最终还是搞定了.当

使用Vitamio打造自己的Android万能播放器(3)——本地播放(主界面、播放列表)

前言 打造一款完整可用的Android播放器有许多功能和细节需要完成,也涉及到各种丰富的知识和内容,本章将结合Fragment.ViewPager来搭建播放器的主界面,并实现本地播放基本功能.系列文章提供截图.代码说明.源码下载,欢迎交流! 声明 欢迎转载,但请保留文章原始出处:) 博客园:http://www.cnblogs.com 农民伯伯: http://over140.cnblogs.com 系列 1.使用Vitamio打造自己的Android万能播放器(1)——准备 2.使用Vitam