【问题标题】:Showing Bitmaps one after another in wxpython at a certain point overlaps them and doesn't show the rest在 wxpython 中的某个点一个接一个地显示位图与它们重叠并且不显示其余部分
【发布时间】:2018-12-14 17:01:00
【问题描述】:

我正在用 Python 构建一个简单的程序来显示存储在某些文件夹中的一些图像。该程序从一个文件夹到另一个文件夹显示一个又一个的图像,如下所示:

for x in range(len(gl)):
    for y in range(tn[x]):
        png = wx.Image("{}\\{}\\{}".format(username, gl[x], pnglist[tot + y]), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
        delpng.append(wx.StaticBitmap(self.scrollWin, -1, png, (0, 56 * (tot + y)), (56, 56)))
    tot += tn[x]

在某个时刻,图像停止正确显示、重叠,然后根本不显示。

Correctly showing images

Overlapping

所有图像的宽度和高度均为 56 像素。我不知道是什么原因造成的。

对于它经过的文件夹: https://www.mediafire.com/file/l5t2uk9d2d1o7o0/GamerM3243.rar/file

至于代码:

import wx

#username = str(input("Username: "))
username = "GamerM3243"
delpng = []

def ShowImages(self, username):
    gl = []
    glif = [0]
    pnglist = []
    rpnglist = []
    tn = []

    fl = open("{}\\{}'s Trophies.txt".format(username, username), "r", encoding = "utf-8-sig").read().split('\n')
    self.scrollWin = wx.ScrolledWindow(self, -1, size = (700, 500))

    for i, n in enumerate(fl):
        if ''.join(list(n)[:25]) == "Number of trophies earned":
            gl.append(fl[i-1])
            tn.append(int(''.join(list(n)[27:])))

    glif = [i for i, n in enumerate(fl) if n in gl]

    for i, n in enumerate(gl):
        gl[i] = ''.join([x for x in list(n) if x != ":" and x != "?" and x != '"'])

    for i, n in enumerate(glif):
        i1 = n + 2
        try: 
            i2 = glif[i + 1] - 1      
        except IndexError:
            i2 = -1
        rpnglist.append(fl[i1:i2])

    for x in rpnglist:
        for y in x:
            if y != "" and y not in gl:
                pnglist.append(y)

    for i, n in enumerate(pnglist):
        for x, z in enumerate(list(n)):
            if z == "-" and n[x - 1] == " " and n[x + 1] == " ":
                pnglist[i] = ''.join(list(n)[:x - 1])

    for i, n in enumerate(pnglist):
        pnglist[i] = "{}.png".format(''.join([x for x in list(n) if x != ":" and x != "?" and x != '"']))

    tot = 0

    for x in range(len(gl)):
        for y in range(tn[x]):
                png = wx.Image("{}\\{}\\{}".format(username, gl[x], pnglist[tot + y]), wx.BITMAP_TYPE_ANY).ConvertToBitmap()
                delpng.append(wx.StaticBitmap(self.scrollWin, -1, png, (0, 56 * (tot + y)), (56, 56)))
        tot += tn[x]

    self.scrollWin.SetScrollbars(0, 1, 1400, 56 * tot)
    self.Layout()
    self.Show(True) 

class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title = title, size = (700, 500))
        ShowImages(self, username)

app = wx.App(False)
frame = MainWindow(None, "{}'s Trophies".format(username))
app.MainLoop()

您只需解压缩文件,然后将 .py 文件放在文件夹外。 感谢您的帮助!

【问题讨论】:

  • 请发布一个最低限度的工作示例和重新创建问题的步骤

标签: python-3.x bitmap wxpython bitmapimage


【解决方案1】:

------------ 编辑 -------------

我运行了代码并打印了对象的位置,看起来它在 wxpython 中达到了一些内部限制。图像达到某个 y 坐标,然后相互叠加。

我尝试使用滚动画布以及将位图添加到 sizer 中,它们都产生了大致相同的结果。

您可能需要重新考虑您的设计。在没有耗尽计算机资源的情况下,可能要显示的项目太多。我建议对图像进行分页以防止一次加载太多图像,或者尝试在 LC_ICON 模式下将它们添加到 listctrl。

我更新了要显示的代码,以用图像填充窗口,而不仅仅是一列。似乎都显示出来了:

import wx

# username = str(input("Username: "))
username = "GamerM3243"
delpng = []


class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(700, 500))
        self.ShowImages(username)

    def ShowImages(self, username):
        gl = []
        glif = [0]
        pnglist = []
        rpnglist = []
        tn = []

        fl = open("{}\\{}'s Trophies.txt".format(username, username), "r", encoding="utf-8-sig").read().split('\n')
        self.scrollWin = wx.ScrolledWindow(self, -1, size=(700, 500))

        for i, n in enumerate(fl):
            if ''.join(list(n)[:25]) == "Number of trophies earned":
                gl.append(fl[i - 1])
                tn.append(int(''.join(list(n)[27:])))

        glif = [i for i, n in enumerate(fl) if n in gl]

        for i, n in enumerate(gl):
            gl[i] = ''.join([x for x in list(n) if x != ":" and x != "?" and x != '"'])

        for i, n in enumerate(glif):
            i1 = n + 2
            try:
                i2 = glif[i + 1] - 1
            except IndexError:
                i2 = -1
            rpnglist.append(fl[i1:i2])

        for x in rpnglist:
            for y in x:
                if y != "" and y not in gl:
                    pnglist.append(y)

        for i, n in enumerate(pnglist):
            for x, z in enumerate(list(n)):
                if z == "-" and n[x - 1] == " " and n[x + 1] == " ":
                    pnglist[i] = ''.join(list(n)[:x - 1])

        for i, n in enumerate(pnglist):
            pnglist[i] = "{}.png".format(''.join([x for x in list(n) if x != ":" and x != "?" and x != '"']))

        tot = 0

        col_count = self.GetSize()[0] // 56
        # col_wid = col_count * 56

        for x in range(len(gl)):
            for y in range(tn[x]):
                png = wx.Image("{}\\{}\\{}".format(username, gl[x], pnglist[tot + y]),
                               wx.BITMAP_TYPE_ANY).ConvertToBitmap()
                # print(56 * (tot + y))

                row, col = divmod(tot + y, col_count)
                pos = (56 * col, 56 * row)
                bmp = wx.StaticBitmap(self.scrollWin, -1, png, pos, (56, 56))

                delpng.append(bmp)

            tot += tn[x]
        self.scrollWin.SetScrollbars(0, 1, 1400, 56 * tot / col_count)
        self.Show()


app = wx.App(False)
frame = MainWindow(None, "{}'s Trophies".format(username))
app.MainLoop()

----------- 编辑 #2 -------------

后续问题可能更适合CodeReview,但这里是仅使用 1 个循环的快速重写:

import wx, os

# username = str(input("Username: "))
username = "GamerM3243"
delpng = []
this_dir = os.path.abspath(".")
img_size = (56, 56)


def remove_illegal_chars(text):
    """
    :param text:
    :type text:
    :return: removes characters from a string that aren't allowed in windows filenames
    :rtype:
    """
    illegal = '":?/\<>|*'
    return "".join(c for c in text if c not in illegal)


def extract_fname(line_text):
    """
    :param line_text: a line of text from trophies.txt
    :type line_text:
    :return: the corresponding file name
    :rtype:
    """
    return remove_illegal_chars(line_text).split(" - Earned on")[0] + ".png"


def get_image_path(username, game_folder, line_text):
    """
    :param username:
    :type username:
    :param game_folder:
    :type game_folder:
    :param line_text:
    :type line_text:
    :return:
    :rtype:
    """
    return os.path.join(this_dir, username, game_folder, extract_fname(line_text))


class MainWindow(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, title=title, size=(700, 500))
        self.scrollWin = None
        self.show_images(username)

    def show_images(self, username):
        self.scrollWin = wx.ScrolledWindow(self, -1, size=(700, 500))

        trophy_path = os.path.join(username, f"{username}'s Trophies.txt")
        with open(trophy_path, "r", encoding="utf-8-sig") as fileobj:
            lines = fileobj.read().split("\n")

        col_count = self.GetSize()[0] // img_size[0]
        last_line = None
        game_folder = None
        total_imgs = 0
        for line in lines:
            if line.startswith("Number of trophies earned"):
                # trophy count line, preceded by game title line
                game_folder = last_line
            elif "Earned on" in line:
                # trophy line
                img_path = get_image_path(username, game_folder, line)
                self.create_image(img_path, total_imgs, col_count)
                total_imgs += 1
            else:
                # possible game title
                last_line = remove_illegal_chars(line)
        self.scrollWin.SetScrollbars(0, 1, 1400, img_size[0] * total_imgs / col_count)
        self.Show()

    def create_image(self, img_path, img_number, col_count):
        bmp = wx.Bitmap(img_path)
        row, col = divmod(img_number, col_count)
        pos = (img_size[0] * col, img_size[0] * row)
        wx.StaticBitmap(self.scrollWin, -1, bmp, pos)


if __name__ == "__main__":
    try:
        app = wx.App(False)
        frame = MainWindow(None, "{}'s Trophies".format(username))
        app.MainLoop()
    except:
        import traceback

        traceback.print_exc()
        input()

【讨论】:

  • 感谢您的回答!从现在开始我会考虑的。但这似乎对我不起作用。我应该在你的评论部分放什么?我试着什么都不放,甚至一个 time.sleep() 但没有任何效果。
  • 谢谢!我的意图是在单列中显示图像并在每个图像旁边都有文本,但如果没有其他工作,我将使用不止一列。我还将尝试对其进行分页或将它们添加到 listctrl。顺便说一句,您对如何缩短所有 for 循环有任何想法吗?并不是说它不能正常工作,而是我希望它更紧凑。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-14
  • 2013-01-01
  • 2010-11-15
相关资源
最近更新 更多