이번에는 프로그램을 종료하는 순간의 윈도우의 위치와 크기를 기억하고 다음에 다시 실행할때 그 위치와 크기로 실행되는
기능을 구현해본다.
1. widgets/main_window.py 수정
메인 윈도우가 종료되는 시점에 호출되는 closeEvent 메소드를 오버라이딩하여 윈도우의 위치와 크기를 설정파일 config.json에
저장하고 실행시에는 설정파일의 내용을 읽어 메인 윈도우의 초기 위치와 크기값을 지정하는 방식으로 기능을 구현하려 한다.
설정파일이 없다면 디폴트 설정을 사용하여 실행하고 종료시에 설정파일을 생성하여 저장하도록 할 것이다.
``` 생략 ```
from controller.config_manager import set_geometry, get_geometry
class MainWindow(QMainWindow):
``` 생략 ```
# 윈도우 위치, 크기 설정
geometry = get_geometry()
if not geometry:
self.init_geometry()
else:
self.setGeometry(*geometry)
``` 생략 ```
# 윈도우 크기 초기설정
def init_geometry(self):
# 윈도우 초기 사이즈 지정
self.resize(1000, 800)
# 모니터 화면의 중앙 위치 정보
center_pos = self.screen().availableGeometry().center()
# 윈도우의 중앙위치를 모니터 화면의 중앙으로 이동
self.frameGeometry().moveCenter(center_pos)
# 종료시 윈도우의 위치와 크기를 설정파일에 저장
def closeEvent(self, event):
QMainWindow.closeEvent(self, event)
set_geometry(self.geometry())
설정파일이 없을 경우 윈도우의 크기와 위치를 디폴트값으로 설정하는 init_geometry 메소드를 정의하고 controller 디렉토리의
config_manage.py 에 정의된 set_geometry 함수가 호출되도록 closeEvent 를 오버라이딩 해준다. 이제 프로그램이 실행될 때는
get_geometry 함수를 호출하여 설정파일의 내용을 읽어 만약 설정파일이 없다면 init_geometry를 호출하여 디폴트값을, 파일이
존재한다면 설정파일의 값을 사용하여 윈도우를 초기화하고 종료될 때는 set_geometry 함수를 호출하여 종료시점의 윈도우의
위치와 크기를 설정파일에 저장하게 된다.
2. controller/config_manager.py 작성
이제 main_window.py 에서 사용한 set_geometry, get_geometry 함수를 실제로 구현할 차례이다.
from json import dump, load, JSONDecodeError
# config 파일의 내용을 불러와 geometry 값을 수정하여 저장
def set_geometry(geometry):
with open('config.json', 'w+') as config_file:
try:
config = load(config_file)
except JSONDecodeError:
config = {}
config['geometry'] = {
'x': geometry.x(),
'y': geometry.y(),
'height': geometry.height(),
'width': geometry.width()
}
dump(config, config_file, indent=4)
# config 파일의 내용을 불러와 geometry 값을 읽어 리스트형태로 반환
def get_geometry():
try:
with open('config.json', 'r') as config_file:
try:
config = load(config_file)
except JSONDecodeError:
return None
except FileNotFoundError:
return None
return [config['geometry'][key] for key in ['x', 'y', 'width', 'height']]
controller 디렉토리의 config_manager.py 를 생성하여 위와 같이 작성한다. 함수의 내용은 간단하다.
set_geometry 는 MainWindow 가 호출시에 넘겨준 geometry 데이터에서 x좌표 y좌표, 높이, 너비를
config.json 파일에 key : value 의 형태로 작성하고 get_geometry 는 반대로 config.json 파일에서 읽어온
geometry 데이터를 리스트의 형태로 반환한다. 만약 config.json 파일이 존재하지 않거나 잘못된 형식의
json 파일이라면 None을 반환한다.
※ 여기까지의 작업으로도 위치, 크기 기억 기능은 정상적으로 작동하지만 최대화한 이후 종료할 경우
다시 프로그램을 실행하여 최소화 하더라도 최대화 상태의 크기와 위치가 되어버리는 문제가 발생한다.
이부분은 현재 해결중이다.
3. 최대화 상태에서 종료할 경우의 문제 해결
``` 생략 ```
# 윈도우 위치, 크기 설정
geometry = get_geometry()
if not geometry:
self.init_geometry()
else:
self.setGeometry(geometry[1], geometry[2], geometry[3], geometry[4])
if geometry[0]:
self.showMaximized()
# 윈도우를 화면에 띄운다
self.show()
``` 생략 ```
# 종료시 윈도우의 위치와 크기를 설정파일에 저장
def closeEvent(self, event):
QMainWindow.closeEvent(self, event)
set_geometry(self.normalGeometry(), self.isMaximized())
생각보다 간단하게 문제를 해결할 수 있었다. set_geometry 를 호출할 때 geometry 대신 normalGeomtery 데이터를
넘겨주고 최대화 여부를 함께 넘겨주어 config 파일에 저장하는 것으로 실행시에도 normalGeomtery 값으로 윈도우를
초기화하고 최대화 여부가 True라면 showMaximized 를 호출하여 최대화된 상태로 보여주는 것으로 해결하였다.
from json import dump, load, JSONDecodeError
# config 파일의 내용을 불러와 geometry 값을 수정하여 저장
def set_geometry(geometry, is_maximized):
with open('config.json', 'w+') as config_file:
try:
config = load(config_file)
except JSONDecodeError:
config = {}
config['geometry'] = {
'max': is_maximized,
'x': geometry.x(),
'y': geometry.y(),
'height': geometry.height(),
'width': geometry.width()
}
dump(config, config_file, indent=4)
# config 파일의 내용을 불러와 geometry 값을 읽어 리스트형태로 반환
def get_geometry():
try:
with open('config.json', 'r') as config_file:
try:
config = load(config_file)
except JSONDecodeError:
return None
except FileNotFoundError:
return None
return [config['geometry'][key] for key in ['max', 'x', 'y', 'width', 'height']]
config_manager 파일도 위와 같이 수정하여 최대화 여부를 geometry 정보에 추가하였다.
이제 최대화 상태로 종료하더라도 일반 상태의 위치와 크기를 기억할 수 있게 되었다.
'개인 프로젝트 > Accounting Program' 카테고리의 다른 글
#13 데이터베이스 연결 (0) | 2021.10.30 |
---|---|
#12 메인 화면 구성 (0) | 2021.10.28 |
#10 프로젝트 구조 변경 (0) | 2021.10.20 |
#9 레이아웃(Layout) (0) | 2021.10.18 |
#8 스타일시트 (0) | 2021.10.18 |