Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/env python
from __future__ import (absolute_import, division, print_function, unicode_literals)
import os
import sys
def parse_old_style_connect(qt_old_line, linenum):
step1 = qt_old_line.split('connect(')[1]
step1 = step1.replace(' ', '')
terms = step1.split(',')
if len(terms) != 3:
raise RuntimeError('This is not right! L{1} {0}'.format(qt_old_line,
linenum))
# leading whitespace
whitespace = ' ' * (len(qt_old_line) - len(qt_old_line.lstrip(' ')))
# widget name
widget_name = terms[0]
# event signal
event_signal = terms[1]
# method to handle event
hander_method = terms[2].replace('(', '').replace(')', '').strip()
return whitespace, widget_name, event_signal, hander_method
def convert_signal_connect(cmd, linenum):
"""
Convert (very) old style signal connection to newer style
"""
try:
if cmd.strip().startswith('#'):
return cmd
if cmd.count('self.connect') != 1:
return cmd
except UnicodeDecodeError:
print('L{} of source file encountered UnicodeDecodeError - not changing line'.format(linenum))
return cmd
whitespace, widget_name, event_signal, handler_method = parse_old_style_connect(cmd, linenum)
if event_signal.count('accepted') > 0:
signal_call = 'accepted'
elif event_signal.count('activated') > 0:
signal_call = 'activated'
elif event_signal.count('clicked') > 0:
signal_call = 'clicked'
elif event_signal.count('currentIndexChanged') > 0:
signal_call = 'currentIndexChanged'
elif event_signal.count('indexChanged') > 0:
# must follow currentIndexChanged
signal_call = 'indexChanged'
elif event_signal.count('stateChanged') > 0:
signal_call = 'stateChanged'
elif event_signal.count('toggled') > 0:
signal_call = 'toggled'
elif event_signal.count('itemSelectionChanged') > 0:
signal_call = 'itemSelectionChanged'
elif event_signal.count('rejected') > 0:
signal_call = 'rejected'
elif event_signal.count('returnPressed') > 0:
signal_call = 'returnPressed'
elif event_signal.count('textChanged') > 0:
signal_call = 'textChanged'
elif event_signal.count('triggered') > 0:
signal_call = 'triggered'
elif event_signal.count('valueChanged') > 0:
signal_call = 'valueChanged'
else:
sys.stderr.write('L{1} signal {0} is not supported - skipping line\n'.format(event_signal, linenum))
return cmd
return '{0}{1}.{2}.connect({3})\n'.format(whitespace, widget_name, signal_call, handler_method)
QT4_TO_QTPY_FIXES = {'QtCore.QEventLoop': ('qtpy.QtCore', 'QEventLoop'),
'QtCore.QFileInfo': ('qtpy.QtCore', 'QFileInfo'),
'QtCore.QRegExp': ('qtpy.QtCore', 'QRegExp'),
'QtCore.QSettings': ('qtpy.QtCore', 'QSettings'),
'QtCore.QThread': ('qtpy.QtCore', 'QThread'),
'QtCore.QUrl': ('qtpy.QtCore', 'QUrl'),
'QtGui.QAction': ('qtpy.QtWidgets', 'QAction'),
'QtGui.QAbstractItemView': ('qtpy.QtWidgets', 'QAbstractItemView'),
'QtGui.QApplication': ('qtpy.QtWidgets', 'QApplication'),
'QtGui.QBrush': ('qtpy.QtGui', 'QBrush'),
'QtGui.QButtonGroup': ('qtpy.QtWidgets', 'QButtonGroup'),
'QtGui.QCheckBox': ('qtpy.QtWidgets', 'QCheckBox'),
'QtGui.QComboBox': ('qtpy.QtWidgets', 'QComboBox'),
'QtGui.QCursor': ('qtpy.QtGui', 'QCursor'),
'QtGui.QDesktopServices': ('qtpy.QGui', 'QDesktopServices'),
'QtGui.QDialog': ('qtpy.QtWidgets', 'QDialog'),
'QtGui.QDoubleValidator': ('qtpy.QtGui', 'QDoubleValidator'),
'QtGui.QDoubleSpinBox': ('qtpy.QtWidgets', 'QDoubleSpinBox'),
'QtGui.QFileDialog': ('qtpy.QtWidgets', 'QFileDialog'),
'QtGui.QFrame': ('qtpy.QtWidgets', 'QFrame'),
'QtGui.QGridLayout': ('qtpy.QtWidgets', 'QGridLayout'),
'QtGui.QGroupBox': ('qtpy.QtWidgets', 'QGroupBox'),
'QtGui.QHeaderView': ('qtpy.QtWidgets', 'QHeaderView'),
'QtGui.QHBoxLayout': ('qtpy.QtWidgets', 'QHBoxLayout'),
'QtGui.QIntValidator': ('qtpy.QtGui', 'QIntValidator'),
'QtGui.QMenu': ('qtpy.QtWidgets', 'QMenu'),
'QtGui.QLabel': ('qtpy.QtWidgets', 'QLabel'),
'QtGui.QLineEdit': ('qtpy.QtWidgets', 'QLineEdit'),
'QtGui.QMainWindow': ('qtpy.QtWidgets', 'QMainWindow'),
'QtGui.QMessageBox': ('qtpy.QtWidgets', 'QMessageBox'),
'QtGui.QPushButton': ('qtpy.QtWidgets', 'QPushButton'),
'QtGui.QRegExpValidator': ('qtpy.QtGui', 'QRegExpValidator'),
'QtGui.QRadioButton': ('qtpy.QtWidgets', 'QRadioButton'),
'QtGui.QScrollBar': ('qtpy.QtWidgets', 'QScrollBar'),
'QtGui.QStandardItem': ('qtpy.QtGui', 'QStandardItem'),
'QtGui.QStatusBar': ('qtpy.QtWidgets', 'QStatusBar'),
'QtGui.QStyleFactory': ('qtpy.QtWidgets', 'QStyleFactory'),
'QtGui.QTableWidgetSelectionRange': ('qtpy.QtWidgets', 'QTableWidgetSelectionRange'),
'QtGui.QTreeView': ('qtpy.QtWidgets', 'QTreeView'),
'QtGui.QSizePolicy': ('qtpy.QtWidgets', 'QSizePolicy'),
'QtGui.QSpacerItem': ('qtpy.QtWidgets', 'QSpacerItem'),
'QtGui.QTableWidgetItem': ('qtpy.QtWidgets', 'QTableWidgetItem'),
'QtGui.QTabWidget': ('qtpy.QtWidgets', 'QTabWidget'),
'QtGui.QTextEdit': ('qtpy.QtWidgets', 'QTextEdit'),
'QtGui.QVBoxLayout': ('qtpy.QtWidgets', 'QVBoxLayout'),
'QtGui.QWidget': ('qtpy.QtWidgets', 'QWidget'),
}
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
def convertToQtPy(command, linenum):
imports = dict()
try:
for old_txt, (import_mod, new_txt) in QT4_TO_QTPY_FIXES.items():
if old_txt in command:
items = imports.get(import_mod, set())
items.add(new_txt)
imports[import_mod] = items
command = command.replace(old_txt, new_txt)
if ('QtCore' in command or 'QtGui' in command) and 'import' not in command:
sys.stderr.write('L{} Found unknown qt call: "{}"\n'.format(linenum,
command.strip()))
except UnicodeDecodeError:
pass # would have already been an issue
return command, imports
def read_and_convert_pyqt4_functions(filename):
# parse and fix file
lines = list()
imports = dict()
with open(filename, 'r') as handle:
for linenum, line in enumerate(handle):
# editors count from 1
line = convert_signal_connect(line, linenum+1)
line, imports_for_line = convertToQtPy(line, linenum+1)
for key, values in imports_for_line.items():
items = imports.get(key, set())
for item in values:
items.add(item)
imports[key] = items
lines.append(line)
if len(imports) > 0:
print('========== Change imports of PyQt4 to be ==========')
for key, values in imports.items():
values = list(values)
values.sort()
values = ', '.join(values)
print('from {} import ({}) # noqa'.format(key, values))
# overwrite with new version since there weren't errors
with open(filename, 'w') as handle:
for line in lines:
handle.write(line)
return lines
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser(description='Convert old qt4 signals to qt5-style')
parser.add_argument('files', nargs='+', help='script to convert')
options = parser.parse_args()
for filename in options.files:
filename = os.path.abspath(os.path.expanduser(filename))
if not os.path.exists(filename):
parser.error('file "{}" does not exist'.format(filename))
read_and_convert_pyqt4_functions(filename)