From a4256d3d2b48327446f0d4f7f2bdd329ed9eb056 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 20 Oct 2013 15:15:09 -0400 Subject: [PATCH 1/5] First Qt5 conversion commit Replaced PyQt4 with PyQt5 and made all adjustments necessary to make dupeGuru start up. --- bootstrap.sh | 2 +- build.py | 4 ++-- hscommon/build.py | 4 ++-- hscommon/desktop.py | 10 +++++----- hscommon/trans.py | 4 ++-- qt/base/app.py | 7 ++++--- qt/base/deletion_options.py | 4 ++-- qt/base/details_dialog.py | 7 ++++--- qt/base/details_table.py | 10 +++++----- qt/base/directories_dialog.py | 13 +++++++------ qt/base/directories_model.py | 9 +++++---- qt/base/ignore_list_dialog.py | 4 ++-- qt/base/preferences.py | 2 +- qt/base/preferences_dialog.py | 8 ++++---- qt/base/prioritize_dialog.py | 4 ++-- qt/base/problem_dialog.py | 4 ++-- qt/base/result_window.py | 10 +++++----- qt/base/results_model.py | 5 +++-- qt/me/details_dialog.py | 4 ++-- qt/me/preferences_dialog.py | 4 ++-- qt/pe/app.py | 2 +- qt/pe/details_dialog.py | 4 ++-- qt/pe/preferences_dialog.py | 2 +- qt/pe/result_window.py | 2 +- qt/run_template.py | 5 +++-- qt/se/details_dialog.py | 6 +++--- qt/se/preferences_dialog.py | 4 ++-- qtlib/about_box.py | 7 ++++--- qtlib/app.py | 2 +- qtlib/column.py | 2 +- qtlib/error_report_dialog.py | 7 ++++--- qtlib/preferences.py | 4 +--- qtlib/progress_window.py | 4 ++-- qtlib/radio_box.py | 4 ++-- qtlib/recent.py | 4 ++-- qtlib/reg.py | 2 +- qtlib/reg_demo_dialog.py | 6 +++--- qtlib/reg_submit_dialog.py | 4 ++-- qtlib/search_edit.py | 8 ++++---- qtlib/selectable_list.py | 3 +-- qtlib/table.py | 6 +++--- qtlib/tree_model.py | 5 +++-- qtlib/util.py | 7 ++++--- 43 files changed, 113 insertions(+), 106 deletions(-) diff --git a/bootstrap.sh b/bootstrap.sh index 21c95b93..1ff59e2f 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -18,7 +18,7 @@ echo "Installing pip requirements" if [ "$(uname)" == "Darwin" ]; then pip install -r requirements-osx.txt else - python3 -c "import PyQt4" >/dev/null 2>&1 || { echo >&2 "PyQt 4.8+ required. Install it and try again. Aborting"; exit 1; } + python3 -c "import PyQt5" >/dev/null 2>&1 || { echo >&2 "PyQt 5.1+ required. Install it and try again. Aborting"; exit 1; } pip install -r requirements.txt fi diff --git a/build.py b/build.py index 5ae90608..8e315047 100644 --- a/build.py +++ b/build.py @@ -149,7 +149,7 @@ def build_qt(edition, dev, conf): print("Building localizations") build_localizations('qt', edition) print("Building Qt stuff") - print_and_do("pyrcc4 -py3 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py'))) + print_and_do("pyrcc5 {0} > {1}".format(op.join('qt', 'base', 'dg.qrc'), op.join('qt', 'base', 'dg_rc.py'))) fix_qt_resource_file(op.join('qt', 'base', 'dg_rc.py')) print("Creating the run.py file") filereplace(op.join('qt', 'run_template.py'), 'run.py', edition=edition) @@ -191,7 +191,7 @@ def build_localizations(ui, edition): shutil.copytree('locale', locale_dest, ignore=shutil.ignore_patterns('*.po', '*.pot')) if ui == 'qt' and not ISLINUX: print("Copying qt_*.qm files into the 'locale' folder") - from PyQt4.QtCore import QLibraryInfo + from PyQt5.QtCore import QLibraryInfo trfolder = QLibraryInfo.location(QLibraryInfo.TranslationsPath) for lang in loc.get_langs('locale'): qmname = 'qt_%s.qm' % lang diff --git a/hscommon/build.py b/hscommon/build.py index dcd7ece0..c578190d 100644 --- a/hscommon/build.py +++ b/hscommon/build.py @@ -196,7 +196,7 @@ def copy_packages(packages_names, dest, create_links=False, extra_ignores=None): shutil.copy(source_path, dest_path) def copy_qt_plugins(folder_names, dest): # This is only for Windows - from PyQt4.QtCore import QLibraryInfo + from PyQt5.QtCore import QLibraryInfo qt_plugin_dir = QLibraryInfo.location(QLibraryInfo.PluginsPath) def ignore(path, names): if path == qt_plugin_dir: @@ -444,7 +444,7 @@ def collect_stdlib_dependencies(script, dest_folder, extra_deps=None): delete_files_with_pattern(op.join(dest_folder, 'distutils'), '*.exe') def fix_qt_resource_file(path): - # pyrcc4 under Windows, if the locale is non-english, can produce a source file with a date + # pyrcc5 under Windows, if the locale is non-english, can produce a source file with a date # containing accented characters. If it does, the encoding is wrong and it prevents the file # from being correctly frozen by cx_freeze. To work around that, we open the file, strip all # comments, and save. diff --git a/hscommon/desktop.py b/hscommon/desktop.py index ea5d707f..b2e89533 100644 --- a/hscommon/desktop.py +++ b/hscommon/desktop.py @@ -46,8 +46,8 @@ try: except ImportError: try: - from PyQt4.QtCore import QUrl - from PyQt4.QtGui import QDesktopServices + from PyQt5.QtCore import QUrl, QStandardPaths + from PyQt5.QtGui import QDesktopServices import os.path as op def _open_path(path): url = QUrl.fromLocalFile(str(path)) @@ -58,10 +58,10 @@ except ImportError: def _special_folder_path(special_folder): if special_folder == SpecialFolder.Cache: - qtfolder = QDesktopServices.CacheLocation + qtfolder = QStandardPaths.CacheLocation else: - qtfolder = QDesktopServices.DataLocation - return str(QDesktopServices.storageLocation(qtfolder)) + qtfolder = QStandardPaths.DataLocation + return QStandardPaths.standardLocations(qtfolder)[0] except ImportError: raise Exception("Can't setup desktop functions!") diff --git a/hscommon/trans.py b/hscommon/trans.py index 89ea67aa..a1106f73 100644 --- a/hscommon/trans.py +++ b/hscommon/trans.py @@ -59,7 +59,7 @@ def get_locale_name(lang): #--- Qt def install_qt_trans(lang=None): - from PyQt4.QtCore import QCoreApplication, QTranslator, QLocale + from PyQt5.QtCore import QCoreApplication, QTranslator, QLocale if not lang: lang = str(QLocale.system().name())[:2] localename = get_locale_name(lang) @@ -116,7 +116,7 @@ def install_gettext_trans_under_qt(base_folder, lang=None): # So, we install the gettext locale, great, but we also should try to install qt_*.qm if # available so that strings that are inside Qt itself over which I have no control are in the # right language. - from PyQt4.QtCore import QCoreApplication, QTranslator, QLocale, QLibraryInfo + from PyQt5.QtCore import QCoreApplication, QTranslator, QLocale, QLibraryInfo if not lang: lang = str(QLocale.system().name())[:2] localename = get_locale_name(lang) diff --git a/qt/base/app.py b/qt/base/app.py index f4d6b378..65125353 100644 --- a/qt/base/app.py +++ b/qt/base/app.py @@ -9,8 +9,9 @@ import sys import os.path as op -from PyQt4.QtCore import QTimer, QObject, QCoreApplication, QUrl, QProcess, SIGNAL, pyqtSignal -from PyQt4.QtGui import QDesktopServices, QFileDialog, QDialog, QMessageBox, QApplication +from PyQt5.QtCore import QTimer, QObject, QCoreApplication, QUrl, QProcess, pyqtSignal +from PyQt5.QtGui import QDesktopServices +from PyQt5.QtWidgets import QApplication, QFileDialog, QDialog, QMessageBox from hscommon.trans import trget from hscommon.plat import ISLINUX @@ -74,7 +75,7 @@ class DupeGuru(QObject): # In some circumstances, the nag is hidden by other window, which may make the user think # that the application haven't launched. QTimer.singleShot(0, self.finishedLaunching) - self.connect(QCoreApplication.instance(), SIGNAL('aboutToQuit()'), self.application_will_terminate) + QCoreApplication.instance().aboutToQuit.connect(self.application_will_terminate) def _setupActions(self): # Setup actions that are common to both the directory dialog and the results window. diff --git a/qt/base/deletion_options.py b/qt/base/deletion_options.py index e42234d1..53bd916f 100644 --- a/qt/base/deletion_options.py +++ b/qt/base/deletion_options.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt -from PyQt4.QtGui import QDialog, QVBoxLayout, QLabel, QCheckBox, QDialogButtonBox +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog, QVBoxLayout, QLabel, QCheckBox, QDialogButtonBox from hscommon.trans import trget from qtlib.radio_box import RadioBox diff --git a/qt/base/details_dialog.py b/qt/base/details_dialog.py index e7f6d9d5..a156c46d 100644 --- a/qt/base/details_dialog.py +++ b/qt/base/details_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt -from PyQt4.QtGui import QDialog +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog from .details_table import DetailsModel @@ -42,5 +42,6 @@ class DetailsDialog(QDialog): #--- model --> view def refresh(self): - self.tableModel.reset() + self.tableModel.beginResetModel() + self.tableModel.endResetModel() diff --git a/qt/base/details_table.py b/qt/base/details_table.py index 91a810a7..884fbedc 100644 --- a/qt/base/details_table.py +++ b/qt/base/details_table.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, SIGNAL, QAbstractTableModel -from PyQt4.QtGui import QHeaderView, QTableView +from PyQt5.QtCore import Qt, QAbstractTableModel +from PyQt5.QtWidgets import QHeaderView, QTableView from hscommon.trans import trget @@ -55,9 +55,9 @@ class DetailsTable(QTableView): hheader.setHighlightSections(False) hheader.setStretchLastSection(False) hheader.resizeSection(0, 100) - hheader.setResizeMode(0, QHeaderView.Fixed) - hheader.setResizeMode(1, QHeaderView.Stretch) - hheader.setResizeMode(2, QHeaderView.Stretch) + hheader.setSectionResizeMode(0, QHeaderView.Fixed) + hheader.setSectionResizeMode(1, QHeaderView.Stretch) + hheader.setSectionResizeMode(2, QHeaderView.Stretch) vheader = self.verticalHeader() vheader.setVisible(False) vheader.setDefaultSectionSize(18) diff --git a/qt/base/directories_dialog.py b/qt/base/directories_dialog.py index 3e4ea3ba..b076ce69 100644 --- a/qt/base/directories_dialog.py +++ b/qt/base/directories_dialog.py @@ -6,10 +6,11 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import QRect -from PyQt4.QtGui import (QWidget, QFileDialog, QHeaderView, QVBoxLayout, QHBoxLayout, QTreeView, - QAbstractItemView, QSpacerItem, QSizePolicy, QPushButton, QApplication, QMainWindow, QMenuBar, - QMenu, QIcon, QPixmap, QLabel) +from PyQt5.QtCore import QRect +from PyQt5.QtWidgets import (QWidget, QFileDialog, QHeaderView, QVBoxLayout, QHBoxLayout, QTreeView, + QAbstractItemView, QSpacerItem, QSizePolicy, QPushButton, QMainWindow, QMenuBar, QMenu, QLabel, + QApplication) +from PyQt5.QtGui import QPixmap, QIcon from hscommon.trans import trget from qtlib.recent import Recent @@ -149,8 +150,8 @@ class DirectoriesDialog(QMainWindow): def _setupColumns(self): header = self.treeView.header() header.setStretchLastSection(False) - header.setResizeMode(0, QHeaderView.Stretch) - header.setResizeMode(1, QHeaderView.Fixed) + header.setSectionResizeMode(0, QHeaderView.Stretch) + header.setSectionResizeMode(1, QHeaderView.Fixed) header.resizeSection(1, 100) def _updateAddButton(self): diff --git a/qt/base/directories_model.py b/qt/base/directories_model.py index 7df5b70c..8cf9272b 100644 --- a/qt/base/directories_model.py +++ b/qt/base/directories_model.py @@ -8,9 +8,10 @@ import urllib.parse -from PyQt4.QtCore import pyqtSignal, Qt, QRect, QUrl, QModelIndex -from PyQt4.QtGui import (QComboBox, QStyledItemDelegate, QApplication, QBrush, QStyle, - QStyleOptionComboBox, QStyleOptionViewItemV4, QItemSelection) +from PyQt5.QtCore import pyqtSignal, Qt, QRect, QUrl, QModelIndex, QItemSelection +from PyQt5.QtWidgets import (QComboBox, QStyledItemDelegate, QStyle, QStyleOptionComboBox, + QStyleOptionViewItem, QApplication) +from PyQt5.QtGui import QBrush from hscommon.trans import trget from qtlib.tree_model import RefNode, TreeModel @@ -29,7 +30,7 @@ class DirectoriesDelegate(QStyledItemDelegate): def paint(self, painter, option, index): self.initStyleOption(option, index) # No idea why, but this cast is required if we want to have access to the V4 valuess - option = QStyleOptionViewItemV4(option) + option = QStyleOptionViewItem(option) if (index.column() == 1) and (option.state & QStyle.State_Selected): cboption = QStyleOptionComboBox() cboption.rect = option.rect diff --git a/qt/base/ignore_list_dialog.py b/qt/base/ignore_list_dialog.py index 169592df..9777c0d0 100644 --- a/qt/base/ignore_list_dialog.py +++ b/qt/base/ignore_list_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt -from PyQt4.QtGui import QDialog, QVBoxLayout, QPushButton, QTableView, QAbstractItemView +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import QDialog, QVBoxLayout, QPushButton, QTableView, QAbstractItemView from hscommon.trans import trget from qtlib.util import horizontalWrap diff --git a/qt/base/preferences.py b/qt/base/preferences.py index 2eabd6b2..bfb592d6 100644 --- a/qt/base/preferences.py +++ b/qt/base/preferences.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtGui import QApplication +from PyQt5.QtWidgets import QApplication from hscommon import trans from qtlib.preferences import Preferences as PreferencesBase diff --git a/qt/base/preferences_dialog.py b/qt/base/preferences_dialog.py index edbed81b..2b5c10d4 100644 --- a/qt/base/preferences_dialog.py +++ b/qt/base/preferences_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import SIGNAL, Qt, QSize -from PyQt4.QtGui import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, +from PyQt5.QtCore import Qt, QSize +from PyQt5.QtWidgets import (QDialog, QDialogButtonBox, QVBoxLayout, QHBoxLayout, QLabel, QComboBox, QSlider, QSizePolicy, QSpacerItem, QCheckBox, QLineEdit, QMessageBox, QSpinBox) from hscommon.plat import ISOSX, ISLINUX @@ -26,8 +26,8 @@ class PreferencesDialogBase(QDialog): self.app = app self._setupUi() - self.connect(self.filterHardnessSlider, SIGNAL("valueChanged(int)"), self.filterHardnessLabel.setNum) - self.connect(self.buttonBox, SIGNAL('clicked(QAbstractButton*)'), self.buttonClicked) + self.filterHardnessSlider.valueChanged['int'].connect(self.filterHardnessLabel.setNum) + self.buttonBox.clicked['QAbstractButton*'].connect(self.buttonClicked) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) diff --git a/qt/base/prioritize_dialog.py b/qt/base/prioritize_dialog.py index 88920762..73d5cc52 100644 --- a/qt/base/prioritize_dialog.py +++ b/qt/base/prioritize_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QMimeData, QByteArray -from PyQt4.QtGui import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QComboBox, QListView, +from PyQt5.QtCore import Qt, QMimeData, QByteArray +from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QComboBox, QListView, QDialogButtonBox, QAbstractItemView, QLabel, QStyle, QSplitter, QWidget, QSizePolicy) from hscommon.trans import trget diff --git a/qt/base/problem_dialog.py b/qt/base/problem_dialog.py index 7c77091a..4310da1c 100644 --- a/qt/base/problem_dialog.py +++ b/qt/base/problem_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt -from PyQt4.QtGui import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QSpacerItem, QSizePolicy, +from PyQt5.QtCore import Qt +from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QSpacerItem, QSizePolicy, QLabel, QTableView, QAbstractItemView, QApplication) from hscommon.trans import trget diff --git a/qt/base/result_window.py b/qt/base/result_window.py index 1ee10b25..bb6438e4 100644 --- a/qt/base/result_window.py +++ b/qt/base/result_window.py @@ -6,9 +6,9 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QUrl, QRect -from PyQt4.QtGui import (QMainWindow, QMenu, QLabel, QDesktopServices, QFileDialog, QMenuBar, - QWidget, QVBoxLayout, QAbstractItemView, QStatusBar, QDialog, QAction, QPushButton, QCheckBox) +from PyQt5.QtCore import Qt, QRect +from PyQt5.QtWidgets import (QMainWindow, QMenu, QLabel, QFileDialog, QMenuBar, QWidget, + QVBoxLayout, QAbstractItemView, QStatusBar, QDialog, QAction, QPushButton, QCheckBox) from hscommon.trans import trget from qtlib.util import moveToScreenCenter, horizontalWrap, createActions @@ -164,7 +164,7 @@ class ResultWindow(QMainWindow): self.resize(630, 514) self.centralwidget = QWidget(self) self.verticalLayout = QVBoxLayout(self.centralwidget) - self.verticalLayout.setMargin(0) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setSpacing(0) self.actionsButton = QPushButton(tr("Actions")) self.detailsButton = QPushButton(tr("Details")) @@ -183,7 +183,7 @@ class ResultWindow(QMainWindow): self.resultsView.verticalHeader().setVisible(False) h = self.resultsView.horizontalHeader() h.setHighlightSections(False) - h.setMovable(True) + h.setSectionsMovable(True) h.setStretchLastSection(False) h.setDefaultAlignment(Qt.AlignLeft) self.verticalLayout.addWidget(self.resultsView) diff --git a/qt/base/results_model.py b/qt/base/results_model.py index 24380853..601fc50a 100644 --- a/qt/base/results_model.py +++ b/qt/base/results_model.py @@ -6,8 +6,9 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, pyqtSignal -from PyQt4.QtGui import QBrush, QFont, QFontMetrics, QTableView, QColor +from PyQt5.QtCore import Qt, pyqtSignal +from PyQt5.QtGui import QBrush, QFont, QFontMetrics, QColor +from PyQt5.QtWidgets import QTableView from qtlib.table import Table diff --git a/qt/me/details_dialog.py b/qt/me/details_dialog.py index 5c2e3b66..a754d3e9 100644 --- a/qt/me/details_dialog.py +++ b/qt/me/details_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import QSize -from PyQt4.QtGui import QVBoxLayout, QAbstractItemView +from PyQt5.QtCore import QSize +from PyQt5.QtGui import QVBoxLayout, QAbstractItemView from hscommon.trans import trget from ..base.details_dialog import DetailsDialog as DetailsDialogBase diff --git a/qt/me/preferences_dialog.py b/qt/me/preferences_dialog.py index 8b699ae8..9fc9fed6 100644 --- a/qt/me/preferences_dialog.py +++ b/qt/me/preferences_dialog.py @@ -7,8 +7,8 @@ # http://www.hardcoded.net/licenses/bsd_license import sys -from PyQt4.QtCore import QSize -from PyQt4.QtGui import (QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QSpacerItem, QWidget, +from PyQt5.QtCore import QSize +from PyQt5.QtWidgets import (QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QSpacerItem, QWidget, QApplication) from hscommon.trans import trget diff --git a/qt/pe/app.py b/qt/pe/app.py index 31ea7a76..d90f18e9 100644 --- a/qt/pe/app.py +++ b/qt/pe/app.py @@ -8,7 +8,7 @@ import logging -from PyQt4.QtGui import QImage, QImageReader, QTransform +from PyQt5.QtGui import QImage, QImageReader, QTransform from core_pe import __appname__ from core_pe.photo import Photo as PhotoBase diff --git a/qt/pe/details_dialog.py b/qt/pe/details_dialog.py index 4fb2ba30..44cb9f55 100644 --- a/qt/pe/details_dialog.py +++ b/qt/pe/details_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QSize -from PyQt4.QtGui import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy, QPixmap +from PyQt5.QtCore import Qt, QSize +from PyQt5.QtGui import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy, QPixmap from hscommon.trans import trget from ..base.details_dialog import DetailsDialog as DetailsDialogBase diff --git a/qt/pe/preferences_dialog.py b/qt/pe/preferences_dialog.py index a0ca7236..ca15d343 100644 --- a/qt/pe/preferences_dialog.py +++ b/qt/pe/preferences_dialog.py @@ -7,7 +7,7 @@ # http://www.hardcoded.net/licenses/bsd_license import sys -from PyQt4.QtGui import QApplication +from PyQt5.QtWidgets import QApplication from hscommon.trans import trget from core.scanner import ScanType diff --git a/qt/pe/result_window.py b/qt/pe/result_window.py index 540da9e1..7fe43b69 100644 --- a/qt/pe/result_window.py +++ b/qt/pe/result_window.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtGui import QMessageBox, QAction +from PyQt5.QtGui import QMessageBox, QAction from hscommon.trans import trget from ..base.result_window import ResultWindow as ResultWindowBase diff --git a/qt/run_template.py b/qt/run_template.py index 73da88c3..0a209897 100644 --- a/qt/run_template.py +++ b/qt/run_template.py @@ -8,8 +8,9 @@ import sys import os.path as op -from PyQt4.QtCore import QCoreApplication, QSettings -from PyQt4.QtGui import QApplication, QIcon, QPixmap +from PyQt5.QtCore import QCoreApplication, QSettings +from PyQt5.QtGui import QIcon, QPixmap +from PyQt5.QtWidgets import QApplication from hscommon.plat import ISWINDOWS from hscommon.trans import install_gettext_trans_under_qt diff --git a/qt/se/details_dialog.py b/qt/se/details_dialog.py index e67a3568..47c892ea 100644 --- a/qt/se/details_dialog.py +++ b/qt/se/details_dialog.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import QSize -from PyQt4.QtGui import QVBoxLayout, QAbstractItemView +from PyQt5.QtCore import QSize +from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView from hscommon.trans import trget from ..base.details_dialog import DetailsDialog as DetailsDialogBase @@ -22,7 +22,7 @@ class DetailsDialog(DetailsDialogBase): self.setMinimumSize(QSize(200, 0)) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) - self.verticalLayout.setMargin(0) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.tableView = DetailsTable(self) self.tableView.setAlternatingRowColors(True) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) diff --git a/qt/se/preferences_dialog.py b/qt/se/preferences_dialog.py index d8f17534..a44105ea 100644 --- a/qt/se/preferences_dialog.py +++ b/qt/se/preferences_dialog.py @@ -7,8 +7,8 @@ # http://www.hardcoded.net/licenses/bsd_license import sys -from PyQt4.QtCore import QSize -from PyQt4.QtGui import (QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QSpacerItem, QWidget, +from PyQt5.QtCore import QSize +from PyQt5.QtWidgets import (QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QSpacerItem, QWidget, QLineEdit, QApplication) from hscommon.plat import ISWINDOWS, ISLINUX diff --git a/qtlib/about_box.py b/qtlib/about_box.py index 00632aad..063a70df 100644 --- a/qtlib/about_box.py +++ b/qtlib/about_box.py @@ -6,9 +6,10 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QCoreApplication -from PyQt4.QtGui import (QDialog, QDialogButtonBox, QPixmap, QSizePolicy, QHBoxLayout, QVBoxLayout, - QLabel, QFont, QApplication) +from PyQt5.QtCore import Qt, QCoreApplication +from PyQt5.QtGui import QPixmap, QFont +from PyQt5.QtWidgets import (QDialog, QDialogButtonBox, QSizePolicy, QHBoxLayout, QVBoxLayout, + QLabel, QApplication) from hscommon.trans import trget diff --git a/qtlib/app.py b/qtlib/app.py index 1fafafce..1426f260 100644 --- a/qtlib/app.py +++ b/qtlib/app.py @@ -7,7 +7,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import SIGNAL, QTimer, QObject +from PyQt5.QtCore import SIGNAL, QTimer, QObject class Application(QObject): def __init__(self): diff --git a/qtlib/column.py b/qtlib/column.py index 7b1ff129..1d9716f7 100644 --- a/qtlib/column.py +++ b/qtlib/column.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt +from PyQt5.QtCore import Qt class Column: def __init__(self, attrname, defaultWidth, editor=None, alignment=Qt.AlignLeft, cantTruncate=False): diff --git a/qtlib/error_report_dialog.py b/qtlib/error_report_dialog.py index baa9ea74..a1d6e7c8 100644 --- a/qtlib/error_report_dialog.py +++ b/qtlib/error_report_dialog.py @@ -10,9 +10,10 @@ import traceback import sys import os -from PyQt4.QtCore import Qt, QUrl, QCoreApplication, QSize -from PyQt4.QtGui import (QDialog, QDesktopServices, QVBoxLayout, QHBoxLayout, QLabel, - QPlainTextEdit, QPushButton, QApplication) +from PyQt5.QtCore import Qt, QUrl, QCoreApplication, QSize +from PyQt5.QtGui import QDesktopServices +from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QLabel, QPlainTextEdit, QPushButton, + QApplication) from hscommon.trans import trget from .util import horizontalSpacer diff --git a/qtlib/preferences.py b/qtlib/preferences.py index 21df10b0..c46ed9e9 100644 --- a/qtlib/preferences.py +++ b/qtlib/preferences.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QSettings, QRect, QPyNullVariant +from PyQt5.QtCore import Qt, QSettings, QRect from hscommon.trans import trget from hscommon.util import tryint @@ -52,8 +52,6 @@ def adjust_after_deserialization(v): return False else: return tryint(v, v) - if isinstance(v, QPyNullVariant): - return None return v # About QRect conversion: diff --git a/qtlib/progress_window.py b/qtlib/progress_window.py index cc7057c0..e9f48dde 100644 --- a/qtlib/progress_window.py +++ b/qtlib/progress_window.py @@ -6,8 +6,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QTimer -from PyQt4.QtGui import QProgressDialog +from PyQt5.QtCore import Qt, QTimer +from PyQt5.QtWidgets import QProgressDialog class ProgressWindow(QProgressDialog): def __init__(self, parent, model): diff --git a/qtlib/radio_box.py b/qtlib/radio_box.py index d786c881..59c58d60 100644 --- a/qtlib/radio_box.py +++ b/qtlib/radio_box.py @@ -5,8 +5,8 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import pyqtSignal -from PyQt4.QtGui import QWidget, QHBoxLayout, QRadioButton +from PyQt5.QtCore import pyqtSignal +from PyQt5.QtWidgets import QWidget, QHBoxLayout, QRadioButton from .util import horizontalSpacer diff --git a/qtlib/recent.py b/qtlib/recent.py index a75b529e..fa17eebe 100644 --- a/qtlib/recent.py +++ b/qtlib/recent.py @@ -8,8 +8,8 @@ from collections import namedtuple -from PyQt4.QtCore import pyqtSignal, QObject -from PyQt4.QtGui import QAction +from PyQt5.QtCore import pyqtSignal, QObject +from PyQt5.QtWidgets import QAction from hscommon.trans import trget from hscommon.util import dedupe diff --git a/qtlib/reg.py b/qtlib/reg.py index c66c578d..891e1971 100644 --- a/qtlib/reg.py +++ b/qtlib/reg.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtGui import QDialog +from PyQt5.QtWidgets import QDialog from .reg_submit_dialog import RegSubmitDialog from .reg_demo_dialog import RegDemoDialog diff --git a/qtlib/reg_demo_dialog.py b/qtlib/reg_demo_dialog.py index e6675d6a..ef6dae6f 100644 --- a/qtlib/reg_demo_dialog.py +++ b/qtlib/reg_demo_dialog.py @@ -8,9 +8,9 @@ import sys -from PyQt4.QtCore import Qt, QCoreApplication -from PyQt4.QtGui import (QDialog, QApplication, QVBoxLayout, QHBoxLayout, QLabel, - QFont, QSpacerItem, QSizePolicy, QPushButton) +from PyQt5.QtCore import Qt, QCoreApplication +from PyQt5.QtWidgets import (QDialog, QApplication, QVBoxLayout, QHBoxLayout, QLabel, QSpacerItem, + QSizePolicy, QPushButton) from hscommon.plat import ISLINUX from hscommon.trans import trget diff --git a/qtlib/reg_submit_dialog.py b/qtlib/reg_submit_dialog.py index 9a55a108..96e5ffa9 100644 --- a/qtlib/reg_submit_dialog.py +++ b/qtlib/reg_submit_dialog.py @@ -8,8 +8,8 @@ import sys -from PyQt4.QtCore import Qt, QCoreApplication -from PyQt4.QtGui import (QDialog, QApplication, QVBoxLayout, QHBoxLayout, QLabel, QFormLayout, +from PyQt5.QtCore import Qt, QCoreApplication +from PyQt5.QtWidgets import (QDialog, QApplication, QVBoxLayout, QHBoxLayout, QLabel, QFormLayout, QLayout, QLineEdit, QPushButton, QSpacerItem, QSizePolicy) from hscommon.trans import trget diff --git a/qtlib/search_edit.py b/qtlib/search_edit.py index e5cd9bc4..5653cb5a 100644 --- a/qtlib/search_edit.py +++ b/qtlib/search_edit.py @@ -6,9 +6,9 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import pyqtSignal, Qt -from PyQt4.QtGui import (QToolButton, QLineEdit, QIcon, QPixmap, QStyle, QStyleOptionFrameV2, - QPainter, QPalette) +from PyQt5.QtCore import pyqtSignal, Qt +from PyQt5.QtGui import QIcon, QPixmap, QPainter, QPalette +from PyQt5.QtWidgets import QToolButton, QLineEdit, QStyle, QStyleOptionFrame from hscommon.trans import trget @@ -66,7 +66,7 @@ class SearchEdit(QLineEdit): def paintEvent(self, event): QLineEdit.paintEvent(self, event) if not bool(self.text()) and self.inactiveText and not self.hasFocus(): - panel = QStyleOptionFrameV2() + panel = QStyleOptionFrame() self.initStyleOption(panel) textRect = self.style().subElementRect(QStyle.SE_LineEditContents, panel, self) leftMargin = 2 diff --git a/qtlib/selectable_list.py b/qtlib/selectable_list.py index 48e96f53..8bbd507a 100644 --- a/qtlib/selectable_list.py +++ b/qtlib/selectable_list.py @@ -6,8 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QAbstractListModel -from PyQt4.QtGui import QItemSelection, QItemSelectionModel +from PyQt5.QtCore import Qt, QAbstractListModel, QItemSelection, QItemSelectionModel class SelectableList(QAbstractListModel): def __init__(self, model, view): diff --git a/qtlib/table.py b/qtlib/table.py index 3e4fea86..90d31338 100644 --- a/qtlib/table.py +++ b/qtlib/table.py @@ -6,8 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt4.QtCore import Qt, QAbstractTableModel, QModelIndex -from PyQt4.QtGui import QItemSelectionModel, QItemSelection +from PyQt5.QtCore import Qt, QAbstractTableModel, QModelIndex, QItemSelectionModel, QItemSelection from .column import Columns @@ -135,7 +134,8 @@ class Table(QAbstractTableModel): #--- model --> view def refresh(self): - self.reset() + self.beginResetModel() + self.endResetModel() self._updateViewSelection() def show_selected_row(self): diff --git a/qtlib/tree_model.py b/qtlib/tree_model.py index 99eb3045..f880c39f 100644 --- a/qtlib/tree_model.py +++ b/qtlib/tree_model.py @@ -8,7 +8,7 @@ import logging -from PyQt4.QtCore import QAbstractItemModel, QModelIndex +from PyQt5.QtCore import QAbstractItemModel, QModelIndex class NodeContainer: def __init__(self): @@ -128,10 +128,11 @@ class TreeModel(QAbstractItemModel, NodeContainer): return self.createIndex(node.parent.row, 0, node.parent) def reset(self): + QAbstractItemModel.beginResetModel(self) self.invalidate() self._ref2node = {} self._dummyNodes = set() - QAbstractItemModel.reset(self) + QAbstractItemModel.endResetModel(self) def rowCount(self, parent=QModelIndex()): node = parent.internalPointer() if parent.isValid() else self diff --git a/qtlib/util.py b/qtlib/util.py index 4f36350f..c3e024c2 100644 --- a/qtlib/util.py +++ b/qtlib/util.py @@ -14,8 +14,9 @@ import logging from hscommon.util import first -from PyQt4.QtGui import (QDesktopWidget, QSpacerItem, QSizePolicy, QPixmap, QIcon, QAction, - QHBoxLayout, QDesktopServices) +from PyQt5.QtCore import QStandardPaths +from PyQt5.QtGui import QPixmap, QIcon +from PyQt5.QtWidgets import QDesktopWidget, QSpacerItem, QSizePolicy, QAction, QHBoxLayout def moveToScreenCenter(widget): frame = widget.frameGeometry() @@ -75,7 +76,7 @@ def setAccelKeys(menu): action.setText(newtext) def getAppData(): - return str(QDesktopServices.storageLocation(QDesktopServices.DataLocation)) + return QStandardPaths.standardLocations(QStandardPaths.DataLocation)[0] class SysWrapper(io.IOBase): def write(self, s): From 664d630b96e90cca47c08e97ed347bd331f57953 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 20 Oct 2013 15:38:24 -0400 Subject: [PATCH 2/5] Fixed occasional core dumps on exit --- qt/run_template.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/qt/run_template.py b/qt/run_template.py index 0a209897..ffe5b36b 100644 --- a/qt/run_template.py +++ b/qt/run_template.py @@ -23,7 +23,7 @@ from core_{edition} import __version__, __appname__ if ISWINDOWS: import qt.base.cxfreeze_fix -if __name__ == "__main__": +def main(): app = QApplication(sys.argv) QCoreApplication.setOrganizationName('Hardcoded Software') QCoreApplication.setApplicationName(__appname__) @@ -41,4 +41,7 @@ if __name__ == "__main__": if not ISWINDOWS: dgapp.model.registered = True install_excepthook() - sys.exit(app.exec_()) + return app.exec() + +if __name__ == "__main__": + sys.exit(main()) From 5a8cb6f5e3261c15e078aa47ddfc6f0a883408a1 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 20 Oct 2013 15:53:59 -0400 Subject: [PATCH 3/5] Implemented super() inheritance style suggested by PyQt5 --- qt/base/app.py | 4 ++-- qt/base/deletion_options.py | 4 ++-- qt/base/details_dialog.py | 6 +++--- qt/base/details_table.py | 4 ++-- qt/base/directories_dialog.py | 4 ++-- qt/base/directories_model.py | 6 +++--- qt/base/ignore_list_dialog.py | 6 +++--- qt/base/preferences_dialog.py | 4 ++-- qt/base/prioritize_dialog.py | 4 ++-- qt/base/problem_dialog.py | 4 ++-- qt/base/problem_table.py | 4 ++-- qt/base/result_window.py | 4 ++-- qt/base/results_model.py | 6 +++--- qt/se/preferences_dialog.py | 4 ++-- qtlib/about_box.py | 4 ++-- qtlib/error_report_dialog.py | 6 +++--- qtlib/progress_window.py | 8 ++++---- qtlib/radio_box.py | 4 ++-- qtlib/recent.py | 4 ++-- qtlib/reg_demo_dialog.py | 4 ++-- qtlib/reg_submit_dialog.py | 4 ++-- qtlib/search_edit.py | 8 ++++---- qtlib/selectable_list.py | 12 ++++++------ qtlib/table.py | 4 ++-- qtlib/tree_model.py | 9 ++++----- 25 files changed, 65 insertions(+), 66 deletions(-) diff --git a/qt/base/app.py b/qt/base/app.py index 65125353..0250d9ee 100644 --- a/qt/base/app.py +++ b/qt/base/app.py @@ -43,8 +43,8 @@ class DupeGuru(QObject): PREFERENCES_CLASS = None PREFERENCES_DIALOG_CLASS = None - def __init__(self): - QObject.__init__(self) + def __init__(self, **kwargs): + super().__init__(**kwargs) self.prefs = self.PREFERENCES_CLASS() self.prefs.load() self.model = self.MODELCLASS(view=self) diff --git a/qt/base/deletion_options.py b/qt/base/deletion_options.py index 53bd916f..8559658a 100644 --- a/qt/base/deletion_options.py +++ b/qt/base/deletion_options.py @@ -15,9 +15,9 @@ from qtlib.radio_box import RadioBox tr = trget('ui') class DeletionOptions(QDialog): - def __init__(self, parent, model): + def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self.model = model self._setupUi() self.model.view = self diff --git a/qt/base/details_dialog.py b/qt/base/details_dialog.py index a156c46d..71eb6923 100644 --- a/qt/base/details_dialog.py +++ b/qt/base/details_dialog.py @@ -12,8 +12,8 @@ from PyQt5.QtWidgets import QDialog from .details_table import DetailsModel class DetailsDialog(QDialog): - def __init__(self, parent, app): - QDialog.__init__(self, parent, Qt.Tool) + def __init__(self, parent, app, **kwargs): + super().__init__(parent, Qt.Tool, **kwargs) self.app = app self.model = app.model.details_panel self._setupUi() @@ -33,7 +33,7 @@ class DetailsDialog(QDialog): def show(self): self._shown_once = True - QDialog.show(self) + super().show() #--- Events def appWillSavePrefs(self): diff --git a/qt/base/details_table.py b/qt/base/details_table.py index 884fbedc..ece4d09a 100644 --- a/qt/base/details_table.py +++ b/qt/base/details_table.py @@ -16,8 +16,8 @@ tr = trget('ui') HEADER = [tr("Attribute"), tr("Selected"), tr("Reference")] class DetailsModel(QAbstractTableModel): - def __init__(self, model): - QAbstractTableModel.__init__(self) + def __init__(self, model, **kwargs): + super().__init__(**kwargs) self.model = model def columnCount(self, parent): diff --git a/qt/base/directories_dialog.py b/qt/base/directories_dialog.py index b076ce69..72fdfd2d 100644 --- a/qt/base/directories_dialog.py +++ b/qt/base/directories_dialog.py @@ -22,8 +22,8 @@ from .directories_model import DirectoriesModel, DirectoriesDelegate tr = trget('ui') class DirectoriesDialog(QMainWindow): - def __init__(self, parent, app): - QMainWindow.__init__(self, None) + def __init__(self, parent, app, **kwargs): + super().__init__(None, **kwargs) self.app = app self.lastAddedFolder = platform.INITIAL_FOLDER_IN_DIALOGS self.recentFolders = Recent(self.app, 'recentFolders') diff --git a/qt/base/directories_model.py b/qt/base/directories_model.py index 8cf9272b..77dbceb2 100644 --- a/qt/base/directories_model.py +++ b/qt/base/directories_model.py @@ -43,7 +43,7 @@ class DirectoriesDelegate(QStyledItemDelegate): rect.setLeft(rect.left()+4) painter.drawText(rect, Qt.AlignLeft, option.text) else: - QStyledItemDelegate.paint(self, painter, option, index) + super().paint(painter, option, index) def setEditorData(self, editor, index): value = index.model().data(index, Qt.EditRole) @@ -59,8 +59,8 @@ class DirectoriesDelegate(QStyledItemDelegate): class DirectoriesModel(TreeModel): - def __init__(self, model, view): - TreeModel.__init__(self) + def __init__(self, model, view, **kwargs): + super().__init__(**kwargs) self.model = model self.model.view = self self.view = view diff --git a/qt/base/ignore_list_dialog.py b/qt/base/ignore_list_dialog.py index 9777c0d0..2acf9dde 100644 --- a/qt/base/ignore_list_dialog.py +++ b/qt/base/ignore_list_dialog.py @@ -16,9 +16,9 @@ from .ignore_list_table import IgnoreListTable tr = trget('ui') class IgnoreListDialog(QDialog): - def __init__(self, parent, model): + def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self._setupUi() self.model = model self.model.view = self @@ -50,5 +50,5 @@ class IgnoreListDialog(QDialog): #--- model --> view def show(self): - QDialog.show(self) + super().show() diff --git a/qt/base/preferences_dialog.py b/qt/base/preferences_dialog.py index 2b5c10d4..fca96872 100644 --- a/qt/base/preferences_dialog.py +++ b/qt/base/preferences_dialog.py @@ -20,9 +20,9 @@ tr = trget('ui') SUPPORTED_LANGUAGES = ['en', 'fr', 'de', 'zh_CN', 'cs', 'it', 'hy', 'ru', 'uk', 'pt_BR', 'vi'] class PreferencesDialogBase(QDialog): - def __init__(self, parent, app): + def __init__(self, parent, app, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self.app = app self._setupUi() diff --git a/qt/base/prioritize_dialog.py b/qt/base/prioritize_dialog.py index 73d5cc52..74429bc5 100644 --- a/qt/base/prioritize_dialog.py +++ b/qt/base/prioritize_dialog.py @@ -52,9 +52,9 @@ class PrioritizationList(ListviewModel): return Qt.MoveAction class PrioritizeDialog(QDialog): - def __init__(self, parent, app): + def __init__(self, parent, app, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self._setupUi() self.model = PrioritizeDialogModel(app=app.model) self.categoryList = ComboboxModel(model=self.model.category_list, view=self.categoryCombobox) diff --git a/qt/base/problem_dialog.py b/qt/base/problem_dialog.py index 4310da1c..b8df3cb6 100644 --- a/qt/base/problem_dialog.py +++ b/qt/base/problem_dialog.py @@ -16,9 +16,9 @@ from .problem_table import ProblemTable tr = trget('ui') class ProblemDialog(QDialog): - def __init__(self, parent, model): + def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self._setupUi() self.model = model self.model.view = self diff --git a/qt/base/problem_table.py b/qt/base/problem_table.py index 855134f3..914903b6 100644 --- a/qt/base/problem_table.py +++ b/qt/base/problem_table.py @@ -15,8 +15,8 @@ class ProblemTable(Table): Column('msg', defaultWidth=150), ] - def __init__(self, model, view): - Table.__init__(self, model, view) + def __init__(self, model, view, **kwargs): + super().__init__(model, view, **kwargs) # we have to prevent Return from initiating editing. # self.view.editSelected = lambda: None \ No newline at end of file diff --git a/qt/base/result_window.py b/qt/base/result_window.py index bb6438e4..fb95f6c3 100644 --- a/qt/base/result_window.py +++ b/qt/base/result_window.py @@ -21,8 +21,8 @@ from .prioritize_dialog import PrioritizeDialog tr = trget('ui') class ResultWindow(QMainWindow): - def __init__(self, app): - QMainWindow.__init__(self, None) + def __init__(self, app, **kwargs): + super().__init__(None, **kwargs) self.app = app self._setupUi() self.resultsModel = app.RESULT_MODEL_CLASS(self.app, self.resultsView) diff --git a/qt/base/results_model.py b/qt/base/results_model.py index 601fc50a..57c8f3ce 100644 --- a/qt/base/results_model.py +++ b/qt/base/results_model.py @@ -13,9 +13,9 @@ from PyQt5.QtWidgets import QTableView from qtlib.table import Table class ResultsModel(Table): - def __init__(self, app, view): + def __init__(self, app, view, **kwargs): model = app.model.result_table - Table.__init__(self, model, view) + super().__init__(model, view, **kwargs) view.horizontalHeader().setSortIndicator(1, Qt.AscendingOrder) app.prefsChanged.connect(self.appPrefsChanged) @@ -109,7 +109,7 @@ class ResultsView(QTableView): if event.text() == ' ': self.spacePressed.emit() return - QTableView.keyPressEvent(self, event) + super().keyPressEvent(event) def mouseDoubleClickEvent(self, event): self.doubleClicked.emit(None) diff --git a/qt/se/preferences_dialog.py b/qt/se/preferences_dialog.py index a44105ea..e65ef70c 100644 --- a/qt/se/preferences_dialog.py +++ b/qt/se/preferences_dialog.py @@ -29,8 +29,8 @@ SCAN_TYPE_ORDER = [ ] class PreferencesDialog(PreferencesDialogBase): - def __init__(self, parent, app): - PreferencesDialogBase.__init__(self, parent, app) + def __init__(self, parent, app, **kwargs): + super().__init__(parent, app, **kwargs) self.scanTypeComboBox.currentIndexChanged[int].connect(self.scanTypeChanged) diff --git a/qtlib/about_box.py b/qtlib/about_box.py index 063a70df..53eb37d9 100644 --- a/qtlib/about_box.py +++ b/qtlib/about_box.py @@ -16,9 +16,9 @@ from hscommon.trans import trget tr = trget('qtlib') class AboutBox(QDialog): - def __init__(self, parent, app, withreg=True): + def __init__(self, parent, app, withreg=True, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.MSWindowsFixedSizeDialogHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self.app = app self.withreg = withreg self._setupUi() diff --git a/qtlib/error_report_dialog.py b/qtlib/error_report_dialog.py index a1d6e7c8..6236a7e5 100644 --- a/qtlib/error_report_dialog.py +++ b/qtlib/error_report_dialog.py @@ -21,9 +21,9 @@ from .util import horizontalSpacer tr = trget('qtlib') class ErrorReportDialog(QDialog): - def __init__(self, parent, error): + def __init__(self, parent, error, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self._setupUi() name = QCoreApplication.applicationName() version = QCoreApplication.applicationVersion() @@ -68,7 +68,7 @@ class ErrorReportDialog(QDialog): text = self.errorTextEdit.toPlainText() url = QUrl("mailto:support@hardcoded.net?SUBJECT=Error Report&BODY=%s" % text) QDesktopServices.openUrl(url) - QDialog.accept(self) + super().accept() def install_excepthook(): diff --git a/qtlib/progress_window.py b/qtlib/progress_window.py index e9f48dde..748070d2 100644 --- a/qtlib/progress_window.py +++ b/qtlib/progress_window.py @@ -10,9 +10,9 @@ from PyQt5.QtCore import Qt, QTimer from PyQt5.QtWidgets import QProgressDialog class ProgressWindow(QProgressDialog): - def __init__(self, parent, model): + def __init__(self, parent, model, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QProgressDialog.__init__(self, '', "Cancel", 0, 100, parent, flags) + super().__init__('', "Cancel", 0, 100, parent, flags, **kwargs) self.model = model model.view = self # We don't have access to QProgressDialog's labels directly, so we se the model label's view @@ -35,7 +35,7 @@ class ProgressWindow(QProgressDialog): def show(self): self.reset() - QProgressDialog.show(self) + super().show() self.canceled.connect(self.model.cancel) self._timer.start(500) @@ -44,5 +44,5 @@ class ProgressWindow(QProgressDialog): # For some weird reason, canceled() signal is sent upon close, whether the user canceled # or not. If we don't want a false cancellation, we have to disconnect it. self.canceled.disconnect() - QProgressDialog.close(self) + super().close() diff --git a/qtlib/radio_box.py b/qtlib/radio_box.py index 59c58d60..e363f523 100644 --- a/qtlib/radio_box.py +++ b/qtlib/radio_box.py @@ -11,12 +11,12 @@ from PyQt5.QtWidgets import QWidget, QHBoxLayout, QRadioButton from .util import horizontalSpacer class RadioBox(QWidget): - def __init__(self, parent=None, items=None, spread=True): + def __init__(self, parent=None, items=None, spread=True, **kwargs): # If spread is False, insert a spacer in the layout so that the items don't use all the # space they're given but rather align left. if items is None: items = [] - QWidget.__init__(self, parent) + super().__init__(parent, **kwargs) self._buttons = [] self._labels = items self._selected_index = 0 diff --git a/qtlib/recent.py b/qtlib/recent.py index fa17eebe..a216cf74 100644 --- a/qtlib/recent.py +++ b/qtlib/recent.py @@ -19,8 +19,8 @@ tr = trget('qtlib') MenuEntry = namedtuple('MenuEntry', 'menu fixedItemCount') class Recent(QObject): - def __init__(self, app, prefName, maxItemCount=10): - QObject.__init__(self) + def __init__(self, app, prefName, maxItemCount=10, **kwargs): + super().__init__(**kwargs) self._app = app self._menuEntries = [] self._prefName = prefName diff --git a/qtlib/reg_demo_dialog.py b/qtlib/reg_demo_dialog.py index ef6dae6f..3b3ef149 100644 --- a/qtlib/reg_demo_dialog.py +++ b/qtlib/reg_demo_dialog.py @@ -18,9 +18,9 @@ from hscommon.trans import trget tr = trget('qtlib') class RegDemoDialog(QDialog): - def __init__(self, parent, reg, prompt): + def __init__(self, parent, reg, prompt, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self.reg = reg self._setupUi() self.descLabel.setText(prompt) diff --git a/qtlib/reg_submit_dialog.py b/qtlib/reg_submit_dialog.py index 96e5ffa9..a3048f6d 100644 --- a/qtlib/reg_submit_dialog.py +++ b/qtlib/reg_submit_dialog.py @@ -17,9 +17,9 @@ from hscommon.trans import trget tr = trget('qtlib') class RegSubmitDialog(QDialog): - def __init__(self, parent, reg): + def __init__(self, parent, reg, **kwargs): flags = Qt.CustomizeWindowHint | Qt.WindowTitleHint | Qt.WindowSystemMenuHint - QDialog.__init__(self, parent, flags) + super().__init__(parent, flags, **kwargs) self._setupUi() self.reg = reg diff --git a/qtlib/search_edit.py b/qtlib/search_edit.py index 5653cb5a..520ac28e 100644 --- a/qtlib/search_edit.py +++ b/qtlib/search_edit.py @@ -18,8 +18,8 @@ tr = trget('qtlib') # "images" folder in your resources. class LineEditButton(QToolButton): - def __init__(self, parent): - QToolButton.__init__(self, parent) + def __init__(self, parent, **kwargs): + super().__init__(parent, **kwargs) pixmap = QPixmap(':/search_clear_13') self.setIcon(QIcon(pixmap)) self.setIconSize(pixmap.size()) @@ -30,9 +30,9 @@ class LineEditButton(QToolButton): class SearchEdit(QLineEdit): - def __init__(self, parent=None, immediate=False): + def __init__(self, parent=None, immediate=False, **kwargs): # immediate: send searchChanged signals at each keystroke. - QLineEdit.__init__(self, parent) + super().__init__(parent, **kwargs) self._clearButton = LineEditButton(self) frameWidth = self.style().pixelMetric(QStyle.PM_DefaultFrameWidth) paddingRight = self._clearButton.sizeHint().width() + frameWidth + 1 diff --git a/qtlib/selectable_list.py b/qtlib/selectable_list.py index 8bbd507a..a51cdd6b 100644 --- a/qtlib/selectable_list.py +++ b/qtlib/selectable_list.py @@ -9,8 +9,8 @@ from PyQt5.QtCore import Qt, QAbstractListModel, QItemSelection, QItemSelectionModel class SelectableList(QAbstractListModel): - def __init__(self, model, view): - QAbstractListModel.__init__(self) + def __init__(self, model, view, **kwargs): + super().__init__(**kwargs) self._updating = False self.view = view self.model = model @@ -49,8 +49,8 @@ class SelectableList(QAbstractListModel): self._restoreSelection() class ComboboxModel(SelectableList): - def __init__(self, model, view): - SelectableList.__init__(self, model, view) + def __init__(self, model, view, **kwargs): + super().__init__(model, view, **kwargs) self.view.currentIndexChanged[int].connect(self.selectionChanged) #--- Override @@ -70,8 +70,8 @@ class ComboboxModel(SelectableList): self._updateSelection() class ListviewModel(SelectableList): - def __init__(self, model, view): - SelectableList.__init__(self, model, view) + def __init__(self, model, view, **kwargs): + super().__init__(model, view, **kwargs) self.view.selectionModel().selectionChanged[(QItemSelection, QItemSelection)].connect( self.selectionChanged) diff --git a/qtlib/table.py b/qtlib/table.py index 90d31338..d47f6f37 100644 --- a/qtlib/table.py +++ b/qtlib/table.py @@ -15,8 +15,8 @@ class Table(QAbstractTableModel): INVALID_INDEX_FLAGS = Qt.ItemIsEnabled COLUMNS = [] - def __init__(self, model, view): - QAbstractTableModel.__init__(self) + def __init__(self, model, view, **kwargs): + super().__init__(**kwargs) self.model = model self.view = view self.view.setModel(self) diff --git a/qtlib/tree_model.py b/qtlib/tree_model.py index f880c39f..abdfe993 100644 --- a/qtlib/tree_model.py +++ b/qtlib/tree_model.py @@ -79,9 +79,8 @@ class DummyNode(TreeNode): pass class TreeModel(QAbstractItemModel, NodeContainer): - def __init__(self): - QAbstractItemModel.__init__(self) - NodeContainer.__init__(self) + def __init__(self, **kwargs): + super().__init__(**kwargs) self._dummyNodes = set() # dummy nodes' reference have to be kept to avoid segfault #--- Private @@ -128,11 +127,11 @@ class TreeModel(QAbstractItemModel, NodeContainer): return self.createIndex(node.parent.row, 0, node.parent) def reset(self): - QAbstractItemModel.beginResetModel(self) + super().beginResetModel() self.invalidate() self._ref2node = {} self._dummyNodes = set() - QAbstractItemModel.endResetModel(self) + super().endResetModel() def rowCount(self, parent=QModelIndex()): node = parent.internalPointer() if parent.isValid() else self From 64d3c211e66963bd534f860305721b6328839006 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 20 Oct 2013 16:26:16 -0400 Subject: [PATCH 4/5] Updated README --- README.md | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 7e577b60..44f7637b 100644 --- a/README.md +++ b/README.md @@ -36,38 +36,23 @@ and follow instructions from the script. You can then ignore the rest of the bui Prerequisites are installed through `pip`. However, some of them are not "pip installable" and have to be installed manually. -* All systems: [Python 3.2+][python] and [setuptools][setuptools] +* All systems: [Python 3.3+][python] and [setuptools][setuptools] * Mac OS X: The last XCode to have the 10.6 SDK included. -* Windows: Visual Studio 2008, [PyQt 4.7+][pyqt], [cx_Freeze][cxfreeze] and +* Windows: Visual Studio 2010, [PyQt 5.0+][pyqt], [cx_Freeze][cxfreeze] and [Advanced Installer][advinst] (you only need the last two if you want to create an installer) -On Ubuntu, the apt-get command to install all pre-requisites is: +On Ubuntu (13.10+), the apt-get command to install all pre-requisites is: - $ apt-get install python3-dev python3-pyqt4 pyqt4-dev-tools python3-setuptools + $ apt-get install python3-dev python3-pyqt5 pyqt5-dev-tools + +On Arch, it's: + + $ pacman -S python-pyqt5 ## Virtualenv setup -First, you need `pip` and `virtualenv` in your system Python install: - - $ sudo easy_install pip - $ sudo pip install virtualenv - -Then, in dupeGuru's source folder, create a virtual environment and activate it: - - $ virtualenv --system-site-packages env - $ source env/bin/activate - -Then, you can install pip requirements in your virtualenv: - - $ pip install -r requirements-[osx|win].txt - -([osx|win] depends, of course, on your platform. On other platforms, just use requirements.txt). - -## Alternative: pyvenv - -If you're on Python 3.3+, you can use the built-in `pyvenv` instead of `virtualenv`. `pyvenv` is -pretty much the same thing as `virtualenv`, except that it doesn't install setuptools and pip, so it -has to be installed manually: +Use the built-in `pyvenv` to setup a virtual environment, and then install `pip` and run the +requirements in it: $ pyvenv --system-site-packages env $ source env/bin/activate From cc5ea1dbc13d3ec0b13f04a2e80c71f16d31fc70 Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sat, 16 Nov 2013 13:38:07 -0500 Subject: [PATCH 5/5] Fixed qt5 migration for ME and PE --- qt/me/details_dialog.py | 4 ++-- qt/me/preferences_dialog.py | 2 +- qt/pe/details_dialog.py | 5 +++-- qt/pe/result_window.py | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/qt/me/details_dialog.py b/qt/me/details_dialog.py index a754d3e9..b651f234 100644 --- a/qt/me/details_dialog.py +++ b/qt/me/details_dialog.py @@ -7,7 +7,7 @@ # http://www.hardcoded.net/licenses/bsd_license from PyQt5.QtCore import QSize -from PyQt5.QtGui import QVBoxLayout, QAbstractItemView +from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView from hscommon.trans import trget from ..base.details_dialog import DetailsDialog as DetailsDialogBase @@ -22,7 +22,7 @@ class DetailsDialog(DetailsDialogBase): self.setMinimumSize(QSize(250, 250)) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) - self.verticalLayout.setMargin(0) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.tableView = DetailsTable(self) self.tableView.setAlternatingRowColors(True) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) diff --git a/qt/me/preferences_dialog.py b/qt/me/preferences_dialog.py index 9fc9fed6..448c3de1 100644 --- a/qt/me/preferences_dialog.py +++ b/qt/me/preferences_dialog.py @@ -50,7 +50,7 @@ class PreferencesDialog(PreferencesDialogBase): self.widget.setMinimumSize(QSize(0, 40)) self.verticalLayout_4 = QVBoxLayout(self.widget) self.verticalLayout_4.setSpacing(0) - self.verticalLayout_4.setMargin(0) + self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) self.label_6 = QLabel(self.widget) self.label_6.setText(tr("Tags to scan:")) self.verticalLayout_4.addWidget(self.label_6) diff --git a/qt/pe/details_dialog.py b/qt/pe/details_dialog.py index 44cb9f55..e9b01678 100644 --- a/qt/pe/details_dialog.py +++ b/qt/pe/details_dialog.py @@ -7,7 +7,8 @@ # http://www.hardcoded.net/licenses/bsd_license from PyQt5.QtCore import Qt, QSize -from PyQt5.QtGui import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy, QPixmap +from PyQt5.QtGui import QPixmap +from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView, QHBoxLayout, QLabel, QSizePolicy from hscommon.trans import trget from ..base.details_dialog import DetailsDialog as DetailsDialogBase @@ -27,7 +28,7 @@ class DetailsDialog(DetailsDialogBase): self.setMinimumSize(QSize(250, 250)) self.verticalLayout = QVBoxLayout(self) self.verticalLayout.setSpacing(0) - self.verticalLayout.setMargin(0) + self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout = QHBoxLayout() self.horizontalLayout.setSpacing(4) self.selectedImage = QLabel(self) diff --git a/qt/pe/result_window.py b/qt/pe/result_window.py index 7fe43b69..ae7bce16 100644 --- a/qt/pe/result_window.py +++ b/qt/pe/result_window.py @@ -6,7 +6,7 @@ # which should be included with this package. The terms are also available at # http://www.hardcoded.net/licenses/bsd_license -from PyQt5.QtGui import QMessageBox, QAction +from PyQt5.QtWidgets import QMessageBox, QAction from hscommon.trans import trget from ..base.result_window import ResultWindow as ResultWindowBase