• R/O
  • HTTP
  • SSH
  • HTTPS

mp2: 提交

Version 2.0 of the minimpy desktop application


Commit MetaInfo

修訂55046a26d22499c8b3f9dc14935b30858870eb58 (tree)
時間2022-02-21 23:15:24
作者Mahmoud Saghaei <mahmood.saghaei@gmai...>
CommiterMahmoud Saghaei

Log Message

File system path for statndalone version

Change Summary

差異

--- a/MinimPy2.spec
+++ b/MinimPy2.spec
@@ -7,7 +7,8 @@ block_cipher = None
77 a = Analysis(['main_window.py'],
88 pathex=['/home/msaghaei/PycharmProjects/minimpy2'],
99 binaries=[],
10- datas=[],
10+ datas=[('db/database.sql', 'db'), ('images/*', 'images'), ('locales/*', 'locales'), ('fa_IR.ts', '.'),
11+ ('minimisation_*.txt', '.'), ('start_*.html', '.'), ('locale_sources.ts', '.')],
1112 hiddenimports=[],
1213 hookspath=[],
1314 runtime_hooks=[],
--- a/about_minimisation.py
+++ b/about_minimisation.py
@@ -2,6 +2,7 @@ from PySide2 import QtWidgets as qtw
22 from os import path
33
44 from ui_about_minimisation import Ui_AboutMinimisationDialog
5+from utils import resource_path
56
67
78 class AboutMinimisationDialog(qtw.QDialog):
@@ -10,9 +11,9 @@ class AboutMinimisationDialog(qtw.QDialog):
1011 self.ui = Ui_AboutMinimisationDialog()
1112 self.ui.setupUi(self)
1213 lang = parent.settings.value('language', 'en_US', type=str)
13- filename = 'minimisation_{}.txt'.format(lang)
14+ filename = resource_path('minimisation_{}.txt'.format(lang))
1415 if not path.exists(filename):
15- filename = 'minimisation_en_US.txt'
16+ filename = resource_path('minimisation_en_US.txt')
1617 if not path.exists(filename):
1718 return
1819 text = open(filename, encoding='utf8').read()
--- a/config.py
+++ b/config.py
@@ -3,6 +3,7 @@ import sys
33 from PySide2 import QtWidgets as qtw
44
55 from config_dialog import Ui_ConfigDialog
6+from utils import resource_path
67
78
89 class Config(qtw.QDialog):
@@ -11,7 +12,7 @@ class Config(qtw.QDialog):
1112 self.parent = parent
1213 self.ui = Ui_ConfigDialog()
1314 self.ui.setupUi(self)
14- lines = open('locales/languages.lst', encoding='utf8').readlines()
15+ lines = open(resource_path('locales/languages.lst'), encoding='utf8').readlines()
1516 self.lang_codes = []
1617 cur_lang = self.parent.settings.value('language', 'en_US', type=str)
1718 cur_index = 0
--- a/db.py
+++ b/db.py
@@ -1,12 +1,16 @@
1-from PySide2 import QtSql as qts
1+from PySide2 import QtSql as qts, QtWidgets
22 from PySide2 import QtWidgets as qtw
33 from PySide2 import QtCore as qtc
44
55 import sys
66 import os
7+from os import path
78
89
910 # noinspection PyTypeChecker
11+from utils import resource_path
12+
13+
1014 class Database(qtc.QObject):
1115 __instance = None
1216
@@ -26,7 +30,7 @@ class Database(qtc.QObject):
2630 'open db: ' + self.db.lastError().text()
2731 )
2832 sys.exit(1)
29- all_sqls = open('db/database.sql', encoding='utf8').read().split(';')
33+ all_sqls = open(resource_path('db/database.sql'), encoding='utf8').read().split(';')
3034 for sql in all_sqls:
3135 query = qts.QSqlQuery(self.db)
3236 query.prepare(sql)
@@ -43,8 +47,16 @@ class Database(qtc.QObject):
4347 raise Exception("This class is a singleton!")
4448 self.mainWindow = mainWindow
4549 self.db = qts.QSqlDatabase.addDatabase('QSQLITE')
46- self.db.setDatabaseName('db/minimizer.db')
47- if not os.path.exists('db/minimizer.db'):
50+ db_path = mainWindow.settings.value('db_path', None, type=str)
51+ if db_path is None or not path.exists(db_path):
52+ db_path = QtWidgets.QFileDialog.getExistingDirectory(mainWindow, 'Select a folder to store your data', '.', QtWidgets.QFileDialog.ShowDirsOnly)
53+ if db_path is None or len(db_path.strip()) == 0:
54+ exit(1)
55+ mainWindow.settings.setValue('db_path', db_path)
56+ if not path.exists(db_path):
57+ os.mkdir(db_path)
58+ self.db.setDatabaseName('{}/minimizer.db'.format(db_path))
59+ if not os.path.exists('{}/minimizer.db'.format(db_path)):
4860 self.create_db()
4961 else:
5062 if not self.db.open():
Binary files a/db/minimizer.db and b/db/minimizer.db differ
--- a/fa_IR.ts
+++ b/fa_IR.ts
@@ -954,6 +954,7 @@ Click and then type over the trial title or code to edit it</source>
954954 <message>
955955 <location filename="main_window.py" line="37"/>
956956 <source>Type of subject identifier. It can be Numeric, Alpha or Alphanumeric.
957+Once a subject is enrolled, you can not change identifier type
957958 </source>
958959 <translation>نوع شناسه نمایش داده شده برای سوژه ها. گزینه های موجود عددی، حرفی و یا حرفی عددی می باشند.\nهنگامی که اولین سوژه وارده مطالعه شد، دیگر نمی توان نوع شناسه را تغییر دارد
959960 </translation>
--- a/freq_table.py
+++ b/freq_table.py
@@ -3,6 +3,8 @@ from PySide2 import QtWidgets as qtw
33 from PySide2 import QtCore as qtc
44 from PySide2 import QtGui as qtg
55
6+from utils import resource_path
7+
68
79 class FreqTable:
810 def __init__(self, parent, ui, trial_id):
@@ -30,11 +32,11 @@ class FreqTable:
3032 return
3133 preload = self.extract_counts()
3234 if self.valid_counts(preload):
33- pixmap = qtg.QPixmap("images/tick_mark.png")
35+ pixmap = qtg.QPixmap(resource_path("images/tick_mark.png"))
3436 self.database.clear_preload(self.trial_id)
3537 self.database.save_preload(self.trial_id, preload)
3638 else:
37- pixmap = qtg.QPixmap("images/error.png")
39+ pixmap = qtg.QPixmap(resource_path("images/error.png"))
3840 self.valid_preload_image.setPixmap(pixmap)
3941
4042 def add_to_preload(self):
Binary files a/locales/fa_IR.qm and b/locales/fa_IR.qm differ
--- a/main_window.py
+++ b/main_window.py
@@ -18,6 +18,8 @@ from run_test import RunTest
1818 from trial import *
1919 import sys
2020 from tendo import singleton
21+from utils import resource_path
22+
2123
2224 # noinspection PyTypeChecker
2325 class MainWindow(qtw.QMainWindow):
@@ -57,17 +59,19 @@ class MainWindow(qtw.QMainWindow):
5759 self.ui = Ui_MainWindow()
5860 self.ui.setupUi(self)
5961 lang = settings.value('language', 'en_US', type=str)
60- filename = 'start_{}.html'.format(lang)
62+ if lang != 'en_US':
63+ self.setLayoutDirection(qtc.Qt.RightToLeft)
64+ filename = resource_path('start_{}.html'.format(lang))
6165 start_str = open(filename, encoding='utf8').read()
6266 self.ui.textEdit.setHtml(start_str)
63- self.ui.actionNew.setIcon(qtg.QIcon('images/add.png'))
64- self.ui.actionDelete.setIcon(qtg.QIcon('images/delete.png'))
65- self.ui.actionLevels.setIcon(qtg.QIcon('images/levels.png'))
66- self.ui.actionSave.setIcon(qtg.QIcon('images/save.png'))
67- self.ui.actionHelp.setIcon(qtg.QIcon('images/help.png'))
68- self.ui.actionQuit.setIcon(qtg.QIcon('images/exit.png'))
69- self.ui.actionConfig.setIcon(qtg.QIcon('images/config.png'))
70- self.ui.actionAbout_MinimPy2.setIcon(qtg.QIcon('images/about.png'))
67+ self.ui.actionNew.setIcon(qtg.QIcon(resource_path('images/add.png')))
68+ self.ui.actionDelete.setIcon(qtg.QIcon(resource_path('images/delete.png')))
69+ self.ui.actionLevels.setIcon(qtg.QIcon(resource_path('images/levels.png')))
70+ self.ui.actionSave.setIcon(qtg.QIcon(resource_path('images/save.png')))
71+ self.ui.actionHelp.setIcon(qtg.QIcon(resource_path('images/help.png')))
72+ self.ui.actionQuit.setIcon(qtg.QIcon(resource_path('images/exit.png')))
73+ self.ui.actionConfig.setIcon(qtg.QIcon(resource_path('images/config.png')))
74+ self.ui.actionAbout_MinimPy2.setIcon(qtg.QIcon(resource_path('images/about.png')))
7175 self.database = Database.get_instance(self)
7276 self.trial = None
7377
@@ -117,8 +121,8 @@ class MainWindow(qtw.QMainWindow):
117121
118122 self.ui.editPreloadCheckBox.toggled.connect(self.on_edit_preload)
119123 self.ui.convertPreloadButton.clicked.connect(self.on_convert_preload)
120- self.ui.factorTableWidget.cellDoubleClicked.connect(self.factor_coloumn_dblclicked)
121- self.ui.subjectTableWidget.cellDoubleClicked.connect(self.subject_coloumn_dblclicked)
124+ self.ui.factorTableWidget.cellDoubleClicked.connect(self.factor_column_dblclicked)
125+ self.ui.subjectTableWidget.cellDoubleClicked.connect(self.subject_column_dblclicked)
122126
123127 self.ui.trialIdentifierLengthSpinBox.valueChanged.connect(self.on_identifier_length)
124128 self.ui.trialBaseProbabilitySlider.valueChanged.connect(self.on_base_prob_change)
@@ -174,6 +178,10 @@ class MainWindow(qtw.QMainWindow):
174178 self.ui.showAtStartCheckBox.setChecked(True)
175179 self.ui.showAtStartCheckBox.toggled.connect(self.toggle_show_at_start)
176180
181+ def on_identifier_length(self, value):
182+ self.trial.identifier_length = value
183+ self.update_sample_size_label()
184+
177185 def toggle_show_at_start(self, check):
178186 self.settings.setValue('show_tutorial_at_start', not check)
179187
@@ -241,7 +249,7 @@ class MainWindow(qtw.QMainWindow):
241249 def on_base_prob_change(self, value):
242250 self.ui.baseProbLabel.setText('{:4.2f}'.format(value / 100.0))
243251
244- def on_identifier_length(self, value):
252+ def on_idenqdialogbuttonboxtifier_length(self, value):
245253 self.trial.identifier_length = value
246254 self.update_sample_size_label()
247255
@@ -367,7 +375,7 @@ class MainWindow(qtw.QMainWindow):
367375 return
368376 self.update_subjects_progress()
369377
370- def subject_coloumn_dblclicked(self, row, col):
378+ def subject_column_dblclicked(self, row, col):
371379 button = qtw.QMessageBox.question(self, self.tr("Warning"),
372380 self.tr('''Are you sure you want to edit subject at row "{}" ?\n
373381 Editing subject may invalidate your research and the result of minimisation''').format(row),
@@ -1014,7 +1022,7 @@ ALL subjects will be deleted'''),
10141022 self.add_factor_row(factor)
10151023 self.ui.factorTableWidget.blockSignals(False)
10161024
1017- def factor_coloumn_dblclicked(self, row, col):
1025+ def factor_column_dblclicked(self, row, col):
10181026 if col != 2:
10191027 return
10201028 self.factor_levels()
@@ -1264,12 +1272,12 @@ def start_app():
12641272 app = qtw.QApplication(sys.argv)
12651273 except RuntimeError:
12661274 app = qtc.QCoreApplication.instance()
1267- app.setWindowIcon(qtg.QIcon('images/logo.png'))
1275+ app.setWindowIcon(qtg.QIcon(resource_path('images/logo.png')))
12681276 settings = qtc.QSettings('net.saghaei', 'minimpy2')
12691277 lang = settings.value('language', 'en_US', type=str)
12701278 if lang != 'en_US':
12711279 translator = qtc.QTranslator()
1272- translator.load('locales/{}'.format(lang))
1280+ translator.load(resource_path('locales/{}'.format(lang)))
12731281 app.installTranslator(translator)
12741282 mw = MainWindow(settings)
12751283 app.mainWindow = mw
--- a/run_test.py
+++ b/run_test.py
@@ -4,6 +4,7 @@ import sys
44
55 class RunTest:
66 def __init__(self, sequence, v1, v2):
7+ #sequence = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1]
78 self.sequence = sequence
89 self.v1, self.v2 = v1, v2
910
--- /dev/null
+++ b/todos.txt
@@ -0,0 +1,9 @@
1+ایرادات
2+MinimPy2
3+تغییر عنوان بلافاصله نشان داده نمی شود
4+
5+تعداد سوژه های وارد شده در Progressbar بروزرسانی نمیشود
6+
7+فیلترها در صفحه سوژه ها بصورت منو باشد
8+
9+تولید لیست رندومیزه
--- a/ui_main_window.ui
+++ b/ui_main_window.ui
@@ -18,7 +18,7 @@
1818 <item>
1919 <widget class="QTabWidget" name="tabWidget">
2020 <property name="currentIndex">
21- <number>7</number>
21+ <number>1</number>
2222 </property>
2323 <widget class="QWidget" name="tab">
2424 <attribute name="title">
@@ -406,8 +406,8 @@
406406 <rect>
407407 <x>0</x>
408408 <y>0</y>
409- <width>760</width>
410- <height>422</height>
409+ <width>98</width>
410+ <height>28</height>
411411 </rect>
412412 </property>
413413 <layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0">
--- /dev/null
+++ b/utils.py
@@ -0,0 +1,12 @@
1+import sys
2+import os
3+
4+
5+def resource_path(relative_path):
6+ """ Get absolute path to resource, works for dev and for PyInstaller """
7+ try:
8+ # PyInstaller creates a temp folder and stores path in _MEIPASS
9+ base_path = sys._MEIPASS
10+ except Exception:
11+ base_path = os.path.abspath(".")
12+ return os.path.join(base_path, relative_path)
Show on old repository browser