0

So lets just say that we have 2 files, file1.py and file2.py, and I need to execute file2.py inside of file1.py, AND after I executed it, I need to transfer a variable called screen from file1.py INTO file2.py, where screen is a manifestation of pygame.display.set_mode() from file1. So in file2.py I tried 2 scenarios:

import pygame, os, time, random, sys, file1
from pygame.locals import *
#some other code

or

import pygame, os, time, random, sys
from pygame.locals import *
from file1 import screen
#some other code

So the part about executing file2 is not a problem, but the part about importing screen IS. The problem is, that the first time file1 tries to execute file2, no error message appears, but no code after import file1 or from file1 import screen works, AND something happens with the pygame window, as images in it get distorted, but after file2 gets executed a second time, it works fine, but the distortions in the pygame window don't disappear.

And after countless tests using print() and time.sleep(), I found out that the source of the problem is the import file1 part, although I have absolutely no idea as to what could be causing it.

Edit: I was asked for a sample of my code to illustrate the problem, so here it is:

file1.py:

import pygame, random, time, sys, os, subprocess
from pygame.locals import *

os.chdir(os.path.dirname(__file__))


pygame.init()
flags = RESIZABLE
size_of_monitor = pygame.display.Info()
width = size_of_monitor.current_w - 25
height = size_of_monitor.current_h - 50
screen = pygame.display.set_mode((width, height), flags)
FPS = 30

black = (0, 0, 0)

mainClock = pygame.time.Clock()

screen_size = screen.get_size()

default_size = (300, 80)

button_image = pygame.image.load(r'orange_button.png')
settings_stretched_image = pygame.transform.scale(button_image, default_size)

settings_rect = settings_stretched_image.get_rect()
settings_rect.centerx = round(width/2)
settings_rect.centery = round(height/2)

exit_stretched_image = pygame.transform.scale(button_image, default_size)
exit_rect = exit_stretched_image.get_rect()
exit_rect.centerx = round(width/2)
exit_rect.centery = round(height/2) + round(150*height/size_of_monitor.current_h)

default_font_size = round(84000/((size_of_monitor.current_w + size_of_monitor.current_h)/2))
font_size = default_font_size
font = pygame.font.SysFont(None, font_size)

def check_if_clicked_button(event_list, settings_rect, exit_rect):
    for event in event_list:
        if event.type == MOUSEBUTTONUP:
            if event.button == 1:
                if settings_rect.collidepoint(event.pos):
                    return 1
                if exit_rect.collidepoint(event.pos):
                    return 2

def draw_text(text, font, surface, color, x, y):
    text_obj = font.render(text, 1, color)
    text_rect = text_obj.get_rect()
    text_rect.centerx = x
    text_rect.centery = y
    surface.blit(text_obj, text_rect)

while True:
    event_list = pygame.event.get()
    result = check_if_clicked_button(event_list, settings_rect, exit_rect)
    if result == 1:
        #open settings
        exec(open(r'settings.py').read())
    if result == 2:
        pygame.quit()
        sys.exit()
    screen.fill(black)
    pygame.Surface.blit(screen, settings_stretched_image, settings_rect)
    pygame.Surface.blit(screen, exit_stretched_image, exit_rect)
    draw_text('Settings', font, screen, black, settings_rect.centerx, settings_rect.centery)
    draw_text('Exit', font, screen, black, exit_rect.centerx, exit_rect.centery)
    pygame.display.update()
    mainClock.tick(FPS)

So this is file1 as simplified as possible. So a couple things that I still have left: a functional exit button on the screen(not on the top right), a game that will crash if gets resized, because I removed about 75% of the code, and a semi functional options button(as I said earlier, on the first press it breaks, but if pressed more, it all works fine), where for the sake of a test, if pressed, a small white square will appear on the window for exactly 1.5 seconds.

And here are the contents of the file2.py:

import pygame, os, time, random, sys
from pygame.locals import *

os.chdir(os.path.dirname(__file__))

from file1 import screen

pygame.init()

for event in pygame.event.get():
    if event.type == QUIT:
        pygame.quit()
        sys.exit()
pygame.draw.rect(screen, (255, 255, 255), (200, 200, 10, 10))
pygame.display.update()
time.sleep(1.5)

not much code, so not much functionality, only used to connect to file1.py and to draw a white square.

And for this to work, both file1.py and file2.py and a picture of a button(I added the one that I used) have to be in the same folder, be named file1.py, file2.py and orange_button.png respectively and start by running file1.py

This is the button I used on the code

hellwraiz
  • 359
  • 2
  • 13
  • why can't you create a screen in file2? – PythonPikachu8 May 09 '21 at 14:45
  • Because if I do that, another instance of a pygame window will appear, but I don’t want that, I want file1 AND file2 to edit the same pygame window – hellwraiz May 09 '21 at 16:59
  • 1
    what are these files actually doing? You need to provide code we can run for both so we can examine the problem. Not the full code, but functional. – marienbad May 10 '21 at 00:42
  • @marienbad sorry for responding so late, I had 2 exams today, so my mom wasn't really happy about me using my laptop. So I edited the question, adding a code sample to it and some brief info. – hellwraiz May 11 '21 at 20:09
  • 1
    In `screen`, don't put code that does things when it's executed in the module namespace. That code should all be in functions, not at the module level. If you want to have a function automatically start when the module is called as a program, that's what `if __name__ == '__main__':` is for. – Charles Duffy May 11 '21 at 20:09
  • 1
    That is to say: In general, any file you're going to `import` from should have _all_ its code inside functions or classes. There are times when it's appropriate to break that rule, but while you're still figuring things out, you aren't encountering those exceptional cases yet. – Charles Duffy May 11 '21 at 20:11
  • @CharlesDuffy is saying what I was going to say...to build on it think in terms of there being two phases when a python program runs. First is the import time when files get imported and related to each other. Do NOT allow any real functionality or initialization of important objects to happen during this phase. Have it all inside a function that is called after everything is imported. Otherwise you run into the way of pain which is where you are now. – Andrew Allaire May 11 '21 at 20:14
  • @CharlesDuffy wait... does that mean that the first time I import screen from file1 it gets executed? and what does ```if __name__ == '__main__':``` even mean? I see it in lots of places, but I just can't understand what it does. – hellwraiz May 11 '21 at 20:15
  • `__name__` is the name of the current module. It's set to the string `'__main__'` only when _that module is the thing you're running as a script_, so `if __name__ == '__main__'` is a way to test if the module you're in is, itself, the script that the interpreter was started to run. And yes, the first time you import a module, all the code in it gets executed -- _all_ of it, not just the code defining the specific names you're trying to import. – Charles Duffy May 11 '21 at 20:17
  • @CharlesDuffy I think I understand what you mean, but just for clarification, does that mean that to avoid my problem I need to put ```screen = pygame.display.set_mode()``` inside of a function, or does that mean that I have to put EVERYTHING, even things like ```ice_cream = 'mint'``` or ```import os``` inside of functions? – hellwraiz May 11 '21 at 20:23
  • `import`s are fine at top-level scope, and so is assigning constants. But anything that has side effects or takes appreciable time probably should be in a function. (`os.chdir()` is an example of something with side effects -- having importing a module change your current directory will be very surprising to users of that module). – Charles Duffy May 11 '21 at 20:24
  • understood, thanks! – hellwraiz May 11 '21 at 20:25

0 Answers0