class ExtendedComboBox(QComboBox):
    def __init__(self):
        QComboBox.__init__(self)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        self.filter_model = QSortFilterProxyModel(self)
        self.filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.filter_model.setSourceModel(self.model())

        self.completer = QCompleter(self.filter_model, self)

        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(
            self.filter_model.setFilterFixedString)

        self.completer.activated.connect(self.on_completer_activated)

    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))

    def setModel(self, model):
        self.setModel(model)
        self.filter_model.setSourceModel(model)
        self.completer.setModel(self.filter_model)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.filter_model.setFilterKeyColumn(column)
        self.setModelColumn(column)
Beispiel #2
0
class ExtendedComboBox(QComboBox):
    """An enhanced version of PyQt5's QComboBox widget that allows for search
    and filtering of the greater list. Implemented by armonge on StackOverflow,
    adapted for PyQt5 by Tamas Haver on StackOverflow.
    
    The Stackoverflow post can be found here:
        
    https://stackoverflow.com/questions/4827207/how-do-i-filter-the-pyqt-qcombobox-items-based-on-the-text-input
    
    """
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QtCore.QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    def on_completer_activated(self, text):
        """On selection of an item from the completer, select the corresponding
        item from combobox.
        """
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))

    def setModel(self, model):
        """On model change, update the models of the filter and completer as 
        well.
        """
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        """On model column change, update the model column of the filter and 
        completer as well.
        """
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)
class ExtendedCombo(QComboBox):
    def __init__(self, items=None, parent=None):
        super().__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())

        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setItems(self, items: list or set):
        self.items = list(items)

        model = QStandardItemModel()

        for i, student in enumerate(items):
            item = UserItem(student)
            model.setItem(i, 0, item)

        self.setModel(model)
        self.setModelColumn(0)

    def setModel(self, model):
        super(ExtendedCombo, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedCombo, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)

    def currentItem(self):
        return self.items[self.currentIndex()]
Beispiel #4
0
 def setup_completer(self):
     """ Sets up the autocomplete on the ancestor """
     completer = QCompleter()
     completer.setModel(self.model)
     completer.setCompletionRole(Qt.DisplayRole)
     completer.setCompletionColumn(self.text_column)
     completer.setCaseSensitivity(Qt.CaseInsensitive)
     completer.setCompletionMode(QCompleter.PopupCompletion)
     completer.setFilterMode(Qt.MatchContains)
     # pylint: disable=unsubscriptable-object
     signal = completer.activated[QModelIndex]
     signal.connect(self.autocomplete_activated)
     self.setCompleter(completer)
Beispiel #5
0
class FilteringComboBox(QComboBox):
    """Combination of QCombobox and QLineEdit with autocompletionself.
    Line edit and completer model is taken from QSqlTable mod

    Args:
        table (str): db table name containing data for combobox
        column (str): column name containing data for combobox
    """
    def __init__(self, table, column, placeholderText, parent=None):
        super(FilteringComboBox, self).__init__(parent)
        self.parent = parent
        self.setEditable(True)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setInsertPolicy(QComboBox.NoInsert)
        self.lineEdit().setPlaceholderText(placeholderText)

        # setup data model
        self._model = QSqlTableModel(self)
        self._model.setTable(table)
        self._model.select()
        col_num = self._model.fieldIndex(column)
        self._model.sort(col_num, Qt.AscendingOrder)
        self.setModel(self._model)
        self.setModelColumn(col_num)

        # setup completer
        self._proxy = QSortFilterProxyModel(self)
        self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self._proxy.setSourceModel(self._model)
        self._proxy.setFilterKeyColumn(col_num)

        self._completer = QCompleter(self)
        self._completer.setModel(self._proxy)
        self._completer.setCompletionColumn(col_num)
        self._completer.activated.connect(self.onCompleterActivated)
        self._completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self._completer)
        self.lineEdit().textEdited.connect(self._proxy.setFilterFixedString)

    @pyqtSlot(str)
    def onCompleterActivated(self, text):
        if not text:
            return

        self.setCurrentIndex(self.findText(text))
        self.activated[str].emit(self.currentText())

    def updateModel(self):
        self._model.select()
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

    def wheelEvent(self, e: QtGui.QWheelEvent) -> None:
        """
            当鼠标轻放在框上,禁止鼠标滚轮滚动选项
        :param e:
        :return:
        """
        pass
Beispiel #7
0
class ExtendedCombo(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedCombo, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())
        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)
        # connect signals
        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)
        self.cur_index = self.currentIndex()
        self.text = self.currentText()

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            C = TextInstance
            C.text = text
        else:
            C = TextInstance
            C.text = self.currentText()

    def update(self):
        return self.text

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedCombo, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedCombo, self).setModelColumn(column)
Beispiel #8
0
class PostSelectionWidget(QDialog):
    def __init__(self, app, parent=None):
        super(PostSelectionWidget, self).__init__(parent=parent)
        self.app = app
        self.model = PostsListModel(app)
        self.filtermodel = QSortFilterProxyModel()
        self.filtermodel.setSourceModel(self.model)
        self.resize(450, 250)
        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        view = QListView(self)
        self.completer = QCompleter(parent=self)
        self.completer.setCompletionMode(QCompleter.InlineCompletion)
        self.completer.setCompletionColumn(0)
        self.completer.setCompletionRole(Qt.DisplayRole)
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setModelSorting(QCompleter.CaseInsensitivelySortedModel)
        self.completer.setModel(self.model)
        self._edit = QLineEdit('')
        self._edit.setCompleter(self.completer)
        self._edit.textEdited.connect(self.setfilter)
        self.layout.addWidget(self._edit)
        self.layout.addWidget(view)
        view.setModel(self.filtermodel)
        view.clicked.connect(self.select)
        view.doubleClicked.connect(self.select_and_edit)
        self._button = QPushButton('Edit')
        self._button.clicked.connect(self.edit)
        self.layout.addWidget(self._button)

    def setfilter(self, text):
        regexp = QRegExp("%s*" % text, Qt.CaseInsensitive, QRegExp.Wildcard)
        self.filtermodel.setFilterRegExp(regexp)

    def select(self, index):
        text = self.filtermodel.data(index)
        self._edit.setText(text)

    def select_and_edit(self, index):
        text = self.filtermodel.data(index)
        self._edit.setText(text)
        self.app.edit_post(text)

    def edit(self):
        self.app.edit_post(self._edit.text())
Beispiel #9
0
class SearchableComboBox(QComboBox):
    def __init__(self, string_list, parent=None):
        super(SearchableComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

        # either fill the standard model of the combobox
        self.addItems(string_list)


    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))


    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(SearchableComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(SearchableComboBox, self).setModelColumn(column)
Beispiel #10
0
class SearchableComboBox(QComboBox):
    def __init__(self, parent=None):
        QComboBox.__init__(self, parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        self.completer = QCompleter(self)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        self.p_filter_model = QSortFilterProxyModel()
        self.p_filter_model.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.completer.popup())

        self.setCompleter(self.completer)

        self.lineEdit().textEdited.connect(
            self.p_filter_model.setFilterFixedString)

    def setModel(self, model):
        super().setModel(model)
        self.p_filter_model.setSourceModel(model)
        self.completer.setModel(self.p_filter_model)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.p_filter_model.setFilterKeyColumn(column)
        super().setModelColumn(column)

    def setTextIfCompleterIsClicked(self, text):
        if text:
            self.setCurrentIndex(self.findText(text))

    def setItems(self, items):
        self.clear()

        model = QStandardItemModel()

        for i, word in enumerate(items):
            item = QStandardItem(word)
            model.setItem(i, 0, item)

        self.setModel(model)
        self.setModelColumn(0)
class ExtendedCombo(QComboBox):
    def __init__(self):
        super().__init__()

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.completer = QCompleter(self)

        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)

        self.completer.setPopup(self.view())

        self.setCompleter(self.completer)

        self.lineEdit().textEdited[str].connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)

    def setModel(self, model):
        super(ExtendedCombo, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedCombo, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
Beispiel #12
0
class FilteredComboBox(QComboBox):
    def __init__(self, options, **kwargs):
        super().__init__()
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        # self.dropEvent()
        self.completer = QCompleter(self)
        # always show all completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setPopup(self.view())
        self.setCompleter(self.completer)
        the_style = "border-top-left-radius: 10px; border-bottom-left-radius: 10px; background-color: #f5f5f5;"
        self.lineEdit().setStyleSheet(the_style)
        if "height" in kwargs:
            self.setFixedHeight(kwargs["height"])
        else:
            self.setFixedHeight(37)

        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.setTextIfCompleterIsClicked)
        model = QStandardItemModel()
        for i, word in enumerate(options):
            item = QStandardItem(word)
            model.setItem(i, 0, item)
        self.setModel(model)
        self.setModelColumn(0)
        if "width" in kwargs:
            self.setFixedWidth(kwargs["width"])
        else:
            self.setFixedWidth(260)

        style = """
        QComboBox {
          border-radius: 10px;
        }

        QComboBox::drop-down:button{
            width: 25px;
            background-color: #f5f5f5;
            border-image: url(./resources/assets/images/drop_down.png);
            border-bottom-right-radius: 10px;
            border-top-right-radius: 10px;
        }

        QComboBox::drop-down:button:hover{
            background-color: #f5f5f5;
        }
        """
        self.setStyleSheet(style)

    def setModel(self, model):
        super(FilteredComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(FilteredComboBox, self).setModelColumn(column)

    def view(self):
        return self.completer.popup()

    def index(self):
        return self.currentIndex()

    def setTextIfCompleterIsClicked(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)

    def setMaximumWidth(self, p_int):
        self.setFixedWidth(p_int)
Beispiel #13
0
class ComboBoxAutocomplete(QComboBox):
    """UI dropdown element with autocomplete.

    Attributes:
        completer (QtWidgets.QCompleter): Autocomplete instance tied to the dropdown items.
        proxy_model (QtWidgets.QSortFilterProxyModel): Configurations of the autocomplete.
    """
    def __init__(self, parent=None):
        """Creates default configurations (case insensitive) and constructs the UI element.

        Args:
            parent (App(QDialog), optional): Object corresponding to the parent UI element.
        """
        super(ComboBoxAutocomplete, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # Setup proxy model to sort and filter data passed between model and view
        self.proxy_model = QSortFilterProxyModel(self)
        self.proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.proxy_model.setSourceModel(self.model())

        # Setup completer
        self.completer = QCompleter(self.proxy_model, self)
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # Connect autocompletion signals
        self.lineEdit().textEdited.connect(
            self.proxy_model.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    # Override
    def on_completer_activated(self, text):
        """Callback event handler for a query in the autocomplete.

        Args:
            text (str): Query text.
        """
        if not text:
            return
        index = self.findText(text)
        self.setCurrentIndex(index)
        self.activated[str].emit(self.itemText(index))

    # Override
    def setModel(self, model):
        """Updates the configuration model.

        Args:
            model (QtWidgets.QSortFilterProxyModel): New configuration to update to.
        """
        super(ComboBoxAutocomplete, self).setModel(model)
        self.proxy_model.setSourceModel(model)
        self.completer.setModel(self.proxy_model)

    # Override
    def setModelColumn(self, column):
        """Updates the column being autocompleted.

        Args:
            column (int): Column from the data used for checking suggestions.
        """
        self.completer.setCompletionColumn(column)
        self.proxy_model.setFilterKeyColumn(column)
        super(ComboBoxAutocomplete, self).setModelColumn(column)
Beispiel #14
0
class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__()

        self.setGeometry(300, 300, 400, 300)

        fid = open('example.db', 'w')
        fid.close()

        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName('example.db')
        db.open()
        query = QSqlQuery(db)

        query.exec_('CREATE TABLE "airports" ("city" TEXT, "code" TEXT)')

        airports = [('Aberdeen, SD', 'ABR'), ('Abilene, TX', 'ABI'),
                    ('Adak Island, AK', 'ADK'), ('Akiachak, AK', 'KKI'),
                    ('Akiak, AK', 'AKI'), ('Akron/Canton, OH', 'CAK'),
                    ('Akuton, AK', 'KQA'), ('Alakanuk, AK', 'AUK'),
                    ('Alamogordo, NM', 'ALM'), ('Alamosa, CO', 'ALS'),
                    ('Albany, NY', 'ALB'), ('Albuquerque, NM', 'ABQ')]
        for item in airports:
            sql = 'INSERT INTO airports(city, code) VALUES(?, ?)'
            query.prepare(sql)
            query.addBindValue(item[0])
            query.addBindValue(item[1])
            query.exec_()

        query.exec_('SELECT * FROM airports')

        model = QSqlQueryModel()
        model.setQuery(query)

        self.cb = QComboBox(parent=self)
        self.cb.setModel(model)
        self.cb.setModelColumn(1)
        self.cb.setView(QTableView(self.cb))
        self.cb.setGeometry(50, 50, 250, 50)
        self.cb.currentIndexChanged.connect(self.indexer)

        self.label = QLabel(parent=self)
        self.label.setGeometry(20, 200, 250, 50)

        self.cb.view().setMinimumWidth(500)
        self.cb.setEditable(True)

        self.completer = QCompleter()
        self.completer.setCaseSensitivity(False)
        self.cb.setCompleter(self.completer)
        self.completer.setModel(model)
        self.completer.setCompletionColumn(1)
        self.completer.setPopup(QTableView())
        self.completer.popup().setMinimumWidth(500)
        self.completer.popup().setMinimumHeight(500)

        self.completer.activated.connect(self.activatedHandler)

    #@pyqtSlot(QObject)
    def activatedHandler(self, arg):
        pass

    def indexer(self, idx):
        self.label.setText('%d' % idx)
Beispiel #15
0
class FilteringComboBox(Widget):
    """Combination of QCombobox and QLineEdit with autocompletionself.
    Line edit and completer model is taken from QSqlTable mod

    Parameters:
        table (str): db table name containing data for combobox
        column (str): column name containing data for combobox
        color (str): 'rgb(r, g, b)' used for primary color
        font_size (int): default text font size in pt
        _model (QSqlTableModel): data model
        _col (int): display data model source coulumn
        _proxy (QSortFilterProxyModel): completer data model.
                                        _proxy.sourceModel() == _model
        _le (QLineEdit): QCombobox LineEdit


    Methods:
        createEditor(): (Widget): returns user input widgets
        value(): (str): returns user input text value
        setValue(value(str)): sets editor widget display value
        style(): (str): Returns CSS stylesheet string for input widget
        updateModel(): updates input widget model

    Args:
        table (str): db table name containing data for combobox
        column (str): column name containing data for combobox
    """
    def __init__(self,
                 parent,
                 placeholderText,
                 table,
                 column,
                 color='rgb(0,145,234)',
                 image=''):
        self.table = table
        self.column = column
        self.color = color
        super().__init__(parent, placeholderText, image)
        self.updateModel()

    def createEditor(self):
        # setup data model
        self._model = QSqlTableModel()
        self._model.setTable(self.table)
        self._col = self._model.fieldIndex(self.column)

        # setup filter model for sorting and filtering
        self._proxy = QSortFilterProxyModel()
        self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self._proxy.setSourceModel(self._model)
        self._proxy.setFilterKeyColumn(self._col)

        # setup completer
        self._completer = QCompleter()
        self._completer.setModel(self._proxy)
        self._completer.setCompletionColumn(self._col)
        self._completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        # setup combobox
        editor = QComboBox()
        editor.setModel(self._proxy)
        editor.setModelColumn(self._col)
        editor.setEditable(True)
        editor.setFocusPolicy(Qt.StrongFocus)
        editor.setInsertPolicy(QComboBox.NoInsert)
        editor.setCompleter(self._completer)

        # setup connections
        editor.currentTextChanged[str].connect(self.onActivated)

        # setup editor appearence
        style = self.style()
        editor.setStyleSheet(style)
        editor.lineEdit().setStyleSheet(style)
        font = editor.font()
        self._completer.popup().setFont(font)

        return editor

    @pyqtSlot(str)
    def onActivated(self, text):
        print('combo_box filter text', text)
        if not text:  # placeholder text displayed and label is not visible
            self._editor.setCurrentIndex(-1)
            if self.toggle:
                self._label.showLabel(False)
        else:  # selected text is displayed and label is visible
            # self._editor.showPopup()
            # self._editor.lineEdit().setFocus()
            print('current copmpletion string',
                  self._completer.currentCompletion())
            self._proxy.setFilterFixedString(text)
            if self.toggle:
                self._label.showLabel(True)

    def style(self):
        """Returns stylesheet for editors

        Returns:
            style (str)
        """
        style = """
            QLineEdit {{
                border: none;
                padding-bottom: 2px;
                border-bottom: 1px solid rgba(0,0,0,0.42);
                background-color: white;
                color: rgba(0,0,0,0.42);
                font-size: {font_size}pt;}}

            QLineEdit:editable {{
                padding-bottom: 2px;
                border-bottom: 1px rgba(0,0,0,0.42);
                color: rgba(0,0,0,0.42);}}

            QLineEdit:disabled {{
                border: none;
                padding-bottom: 2px;
                border-bottom: 1px rgba(0,0,0,0.42);
                color: rgba(0,0,0,0.38);}}

            QLineEdit:hover {{
                padding-bottom: 2px;
                border-bottom: 2px solid rgba(0,0,0,0.6);
                color: rgba(0,0,0,0.54);
                }}

            QLineEdit:focus {{
                padding-bottom: 2px;
                border-bottom: 2px solid {color};
                color: rgba(0,0,0,0.87);}}

            QLineEdit:pressed {{
                border-bottom: 2px {color};
                font: bold;
                color: rgba(0,0,0,0.87)}}

            QComboBox {{
                border: none;
                padding-bottom: 2px;
                font-size: {font_size}pt;
                }}

            QComboBox::down-arrow {{
                image: url('dropdown.png');
                background-color: white;
                border: 0px white;
                padding: 0px;
                margin: 0px;
                height:14px;
                width:14px;}}

            QComboBox::drop-down{{
                subcontrol-position: center right;
                border: 0px;
                margin: 0px;
            }}

            QComboBox QAbstractItemView {{
                font: {font_size};}}

        """.format(color=self.color,
                   font_size=self._editor_font_size,
                   dropdown=DROPDOWN_PNG)
        return style

    def updateModel(self):
        model = self._editor.model().sourceModel()
        col = self._editor.modelColumn()
        model.select()
        model.sort(col, Qt.AscendingOrder)

    def value(self):
        return self._editor.currentText()

    def setValue(self, value):
        self._editor.setCurrentText(value)
Beispiel #16
0
    def init_toolbar(self):
        self.toolbar = QToolBar()
        self.toolbar.setFixedHeight(25)
        self.toolbar.setWindowTitle("Show")  # text for the contextmenu
        # self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined?
        self.toolbar.setMovable(False)
        self.toolbar.setFloatable(False)
        # self.toolbar.setIconSize(QSize(20,20))
        self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)

        spacer_start = QWidget()  # aligns the first actions properly
        spacer_start.setFixedSize(QSize(10, 1))
        self.toolbar.addWidget(spacer_start)

        favourite_view_icon = QIcon(gui_constants.STAR_BTN_PATH)
        favourite_view_action = QAction(favourite_view_icon, "Favorites", self)
        favourite_view_action.setToolTip("Show only favourite galleries")
        favourite_view_action.triggered.connect(self.favourite_display)  # need lambda to pass extra args
        self.toolbar.addAction(favourite_view_action)

        catalog_view_icon = QIcon(gui_constants.HOME_BTN_PATH)
        catalog_view_action = QAction(catalog_view_icon, "Library", self)
        catalog_view_action.setToolTip("Show all your galleries")
        # catalog_view_action.setText("Catalog")
        catalog_view_action.triggered.connect(self.catalog_display)  # need lambda to pass extra args
        self.toolbar.addAction(catalog_view_action)
        self.toolbar.addSeparator()

        gallery_menu = QMenu()
        gallery_action = QToolButton()
        gallery_action.setText("Gallery ")
        gallery_action.setPopupMode(QToolButton.InstantPopup)
        gallery_action.setToolTip("Contains various gallery related features")
        gallery_action.setMenu(gallery_menu)
        add_gallery_icon = QIcon(gui_constants.PLUS_PATH)
        gallery_action_add = QAction(add_gallery_icon, "Add gallery", self)
        gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit)
        gallery_action_add.setToolTip("Add a single gallery thoroughly")
        gallery_menu.addAction(gallery_action_add)
        add_more_action = QAction(add_gallery_icon, "Add galleries...", self)
        add_more_action.setStatusTip("Add galleries from different folders")
        add_more_action.triggered.connect(lambda: self.populate(True))
        gallery_menu.addAction(add_more_action)
        populate_action = QAction(add_gallery_icon, "Populate from folder...", self)
        populate_action.setStatusTip("Populates the DB with galleries from a single folder")
        populate_action.triggered.connect(self.populate)
        gallery_menu.addAction(populate_action)
        gallery_menu.addSeparator()
        metadata_action = QAction("Get metadata for all galleries", self)
        metadata_action.triggered.connect(self.get_metadata)
        gallery_menu.addAction(metadata_action)
        self.toolbar.addWidget(gallery_action)
        self.toolbar.addSeparator()

        misc_action = QToolButton()
        misc_action.setText("Misc ")
        misc_action_menu = QMenu()
        misc_action.setMenu(misc_action_menu)
        misc_action.setPopupMode(QToolButton.InstantPopup)
        misc_action.setToolTip("Contains misc. features")
        misc_action_random = QAction("Open random gallery", misc_action_menu)
        misc_action_random.triggered.connect(self.manga_list_view.open_random_gallery)
        misc_action_menu.addAction(misc_action_random)
        duplicate_check_simple = QAction("Simple duplicate finder", misc_action_menu)
        duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check())
        misc_action_menu.addAction(duplicate_check_simple)
        self.toolbar.addWidget(misc_action)

        spacer_middle = QWidget()  # aligns buttons to the right
        spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.toolbar.addWidget(spacer_middle)

        self.grid_toggle_g_icon = QIcon(gui_constants.GRID_PATH)
        self.grid_toggle_l_icon = QIcon(gui_constants.LIST_PATH)
        self.grid_toggle = QToolButton()
        if self.display.currentIndex() == self.m_l_view_index:
            self.grid_toggle.setIcon(self.grid_toggle_l_icon)
        else:
            self.grid_toggle.setIcon(self.grid_toggle_g_icon)
        self.grid_toggle.setObjectName("gridtoggle")
        self.grid_toggle.clicked.connect(self.toggle_view)
        self.toolbar.addWidget(self.grid_toggle)

        self.search_bar = misc.LineEdit()
        if gui_constants.SEARCH_AUTOCOMPLETE:
            completer = QCompleter(self)
            completer.setModel(self.manga_list_view.gallery_model)
            completer.setCaseSensitivity(Qt.CaseInsensitive)
            completer.setCompletionMode(QCompleter.PopupCompletion)
            completer.setCompletionRole(Qt.DisplayRole)
            completer.setCompletionColumn(gui_constants.TITLE)
            completer.setFilterMode(Qt.MatchContains)
            self.search_bar.setCompleter(completer)
        if gui_constants.SEARCH_ON_ENTER:
            self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text()))
        else:
            self.search_bar.textChanged[str].connect(self.search)
        self.search_bar.setPlaceholderText("Search title, artist, namespace & tags")
        self.search_bar.setMinimumWidth(150)
        self.search_bar.setMaximumWidth(500)
        self.toolbar.addWidget(self.search_bar)
        self.toolbar.addSeparator()
        settings_icon = QIcon(gui_constants.SETTINGS_PATH)
        settings_action = QAction("Set&tings", self)
        settings_action.triggered.connect(self.settings)
        self.toolbar.addAction(settings_action)

        spacer_end = QWidget()  # aligns About action properly
        spacer_end.setFixedSize(QSize(10, 1))
        self.toolbar.addWidget(spacer_end)
        self.addToolBar(self.toolbar)
Beispiel #17
0
	def init_toolbar(self):
		self.toolbar = QToolBar()
		self.toolbar.setFixedHeight(25)
		self.toolbar.setWindowTitle("Show") # text for the contextmenu
		#self.toolbar.setStyleSheet("QToolBar {border:0px}") # make it user defined?
		self.toolbar.setMovable(False)
		self.toolbar.setFloatable(False)
		#self.toolbar.setIconSize(QSize(20,20))
		self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
		self.toolbar.setIconSize(QSize(20,20))

		spacer_start = QWidget() # aligns the first actions properly
		spacer_start.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_start)

		self.favourite_btn = misc.ToolbarButton(self.toolbar, 'Favorites')
		self.toolbar.addWidget(self.favourite_btn)
		self.favourite_btn.clicked.connect(self.favourite_display) #need lambda to pass extra args

		self.library_btn = misc.ToolbarButton(self.toolbar, 'Library')
		self.toolbar.addWidget(self.library_btn)
		self.library_btn.clicked.connect(self.catalog_display) #need lambda to pass extra args
		self.library_btn.selected = True

		self.toolbar.addSeparator()

		gallery_menu = QMenu()
		gallery_action = QToolButton()
		gallery_action.setText('Gallery ')
		gallery_action.setPopupMode(QToolButton.InstantPopup)
		gallery_action.setToolTip('Contains various gallery related features')
		gallery_action.setMenu(gallery_menu)
		add_gallery_icon = QIcon(app_constants.PLUS_PATH)
		gallery_action_add = QAction(add_gallery_icon, "Add single gallery...", self)
		gallery_action_add.triggered.connect(self.manga_list_view.SERIES_DIALOG.emit)
		gallery_action_add.setToolTip('Add a single gallery thoroughly')
		gallery_menu.addAction(gallery_action_add)
		add_more_action = QAction(add_gallery_icon, "Add galleries...", self)
		add_more_action.setStatusTip('Add galleries from different folders')
		add_more_action.triggered.connect(lambda: self.populate(True))
		gallery_menu.addAction(add_more_action)
		populate_action = QAction(add_gallery_icon, "Populate from directory/archive...", self)
		populate_action.setStatusTip('Populates the DB with galleries from a single folder or archive')
		populate_action.triggered.connect(self.populate)
		gallery_menu.addAction(populate_action)
		gallery_menu.addSeparator()
		metadata_action = QAction('Get metadata for all galleries', self)
		metadata_action.triggered.connect(self.get_metadata)
		gallery_menu.addAction(metadata_action)
		scan_galleries_action = QAction('Scan for new galleries', self)
		scan_galleries_action.triggered.connect(self.scan_for_new_galleries)
		scan_galleries_action.setStatusTip('Scan monitored folders for new galleries')
		gallery_menu.addAction(scan_galleries_action)
		gallery_action_random = gallery_menu.addAction("Open random gallery")
		gallery_action_random.triggered.connect(self.manga_list_view.open_random_gallery)
		self.toolbar.addWidget(gallery_action)


		misc_action = QToolButton()
		misc_action.setText('Tools ')
		misc_action_menu = QMenu()
		misc_action.setMenu(misc_action_menu)
		misc_action.setPopupMode(QToolButton.InstantPopup)
		misc_action.setToolTip("Contains misc. features")
		gallery_downloader = QAction("Gallery Downloader", misc_action_menu)
		gallery_downloader.triggered.connect(self.download_window.show)
		misc_action_menu.addAction(gallery_downloader)
		duplicate_check_simple = QAction("Simple Duplicate Finder", misc_action_menu)
		duplicate_check_simple.triggered.connect(lambda: self.manga_list_view.duplicate_check())
		misc_action_menu.addAction(duplicate_check_simple)
		self.toolbar.addWidget(misc_action)

		spacer_middle = QWidget() # aligns buttons to the right
		spacer_middle.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
		self.toolbar.addWidget(spacer_middle)


		sort_action = QToolButton()
		sort_action.setIcon(QIcon(app_constants.SORT_PATH))
		sort_action.setMenu(misc.SortMenu(self.toolbar, self.manga_list_view))
		sort_action.setPopupMode(QToolButton.InstantPopup)
		self.toolbar.addWidget(sort_action)
		
		self.grid_toggle_g_icon = QIcon(app_constants.GRID_PATH)
		self.grid_toggle_l_icon = QIcon(app_constants.LIST_PATH)
		self.grid_toggle = QToolButton()
		if self.display.currentIndex() == self.m_l_view_index:
			self.grid_toggle.setIcon(self.grid_toggle_l_icon)
		else:
			self.grid_toggle.setIcon(self.grid_toggle_g_icon)
		self.grid_toggle.setObjectName('gridtoggle')
		self.grid_toggle.clicked.connect(self.toggle_view)
		self.toolbar.addWidget(self.grid_toggle)

		spacer_mid2 = QWidget()
		spacer_mid2.setFixedSize(QSize(5, 1))
		self.toolbar.addWidget(spacer_mid2)

		def set_search_case(b):
			app_constants.GALLERY_SEARCH_CASE = b
			settings.set(b, 'Application', 'gallery search case')
			settings.save()

		def set_search_strict(b):
			app_constants.GALLERY_SEARCH_STRICT = b
			settings.set(b, 'Application', 'gallery search strict')
			settings.save()

		self.search_bar = misc.LineEdit()
		search_options = self.search_bar.addAction(QIcon(app_constants.SEARCH_OPTIONS_PATH), QLineEdit.TrailingPosition)
		search_options_menu = QMenu(self)
		search_options.triggered.connect(lambda: search_options_menu.popup(QCursor.pos()))
		search_options.setMenu(search_options_menu)
		case_search_option = search_options_menu.addAction('Case Sensitive')
		case_search_option.setCheckable(True)
		case_search_option.setChecked(app_constants.GALLERY_SEARCH_CASE)
		case_search_option.toggled.connect(set_search_case)
		strict_search_option = search_options_menu.addAction('Match whole terms')
		strict_search_option.setCheckable(True)
		strict_search_option.setChecked(app_constants.GALLERY_SEARCH_STRICT)
		strict_search_option.toggled.connect(set_search_strict)
		self.search_bar.setObjectName('search_bar')
		self.search_timer = QTimer(self)
		self.search_timer.setSingleShot(True)
		self.search_timer.timeout.connect(lambda: self.search(self.search_bar.text()))
		self._search_cursor_pos = [0, 0]
		def set_cursor_pos(old, new):
			self._search_cursor_pos[0] = old
			self._search_cursor_pos[1] = new
		self.search_bar.cursorPositionChanged.connect(set_cursor_pos)

		if app_constants.SEARCH_AUTOCOMPLETE:
			completer = QCompleter(self)
			completer_view = misc.CompleterPopupView()
			completer.setPopup(completer_view)
			completer_view._setup()
			completer.setModel(self.manga_list_view.gallery_model)
			completer.setCaseSensitivity(Qt.CaseInsensitive)
			completer.setCompletionMode(QCompleter.PopupCompletion)
			completer.setCompletionRole(Qt.DisplayRole)
			completer.setCompletionColumn(app_constants.TITLE)
			completer.setFilterMode(Qt.MatchContains)
			self.search_bar.setCompleter(completer)
			self.search_bar.returnPressed.connect(lambda: self.search(self.search_bar.text()))
		if not app_constants.SEARCH_ON_ENTER:
			self.search_bar.textEdited.connect(lambda: self.search_timer.start(800))
		self.search_bar.setPlaceholderText("Search title, artist, namespace & tags")
		self.search_bar.setMinimumWidth(150)
		self.search_bar.setMaximumWidth(500)
		self.search_bar.setFixedHeight(19)
		self.manga_list_view.sort_model.HISTORY_SEARCH_TERM.connect(lambda a: self.search_bar.setText(a))
		self.toolbar.addWidget(self.search_bar)

		def search_history(_, back=True): # clicked signal passes a bool
			sort_model =  self.manga_list_view.sort_model
			nav = sort_model.PREV if back else sort_model.NEXT
			history_term = sort_model.navigate_history(nav)
			if back:
				self.search_forward.setVisible(True)

		back = QShortcut(QKeySequence(QKeySequence.Back), self, lambda: search_history(None))
		forward = QShortcut(QKeySequence(QKeySequence.Forward), self, lambda: search_history(None, False))

		search_backbutton = QToolButton(self.toolbar)
		search_backbutton.setText(u'\u25C0')
		search_backbutton.setFixedWidth(15)
		search_backbutton.clicked.connect(search_history)
		self.search_backward = self.toolbar.addWidget(search_backbutton)
		self.search_backward.setVisible(False)
		search_forwardbutton = QToolButton(self.toolbar)
		search_forwardbutton.setText(u'\u25B6')
		search_forwardbutton.setFixedWidth(15)
		search_forwardbutton.clicked.connect(lambda: search_history(None, False))
		self.search_forward = self.toolbar.addWidget(search_forwardbutton)
		self.search_forward.setVisible(False)

		spacer_end = QWidget() # aligns settings action properly
		spacer_end.setFixedSize(QSize(10, 1))
		self.toolbar.addWidget(spacer_end)

		settings_act = QToolButton(self.toolbar)
		settings_act.setIcon(QIcon(app_constants.SETTINGS_PATH))
		settings_act.clicked.connect(self.settings)
		self.toolbar.addWidget(settings_act)

		spacer_end2 = QWidget() # aligns About action properly
		spacer_end2.setFixedSize(QSize(5, 1))
		self.toolbar.addWidget(spacer_end2)
		self.addToolBar(self.toolbar)
Beispiel #18
0
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)
        self.start = False
        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.setStyleSheet('''
QListView {background-color:#AFEEEE}
QListView::item:selected { color: red; background-color: lightgray; min-width: 1000px; }
QComboBox { color:black;max-width: 500px; min-height: 40px;background-color:#AFEEEE}
QComboBox QAbstractItemView::item { min-height: 150px;background-color:#AFEEEE}



''')
        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)
        self.currentIndexChanged.connect(self.selectionchange)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

    def selectionchange(self, i):
        if self.start == False:
            return
        global rows
        libros = []
        txt = self.itemText(i)
        exPopup = ExamplePopup(txt, self)

        for i in rows:
            if txt == i['Título']:
                libros.append(i)
                exPopup.filltable(libros)
                exPopup.show()
                return
            elif txt == i['Autor']:
                libros.append(i)
        exPopup.filltable(libros)
        exPopup.show()
class ExtendedComboBox(QComboBox):
    isHidden = pyqtSignal()

    def __init__(self, gtoAction, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.gtomain = gtoAction.gtomain
        self.debug = gtoAction.debug
        self.info = gtoAction.info
        self.config = gtoAction.config
        self.tools = []
        self.doQueryOnShow = False

        # speed up
        # //  For performance reasons use this policy on large models
        # // or AdjustToMinimumContentsLengthWithIcon
        self.setSizeAdjustPolicy(QComboBox.AdjustToMinimumContentsLength)

        #  // Improving Performance:  It is possible to give the view hints
        # // about the data it is handling in order to improve its performance
        # // when displaying large numbers of items. One approach that can be taken
        # // for views that are intended to display items with equal sizes
        # // is to set the uniformItemSizes property to true.
        self.view().setUniformItemSizes(True)
        #  // This property holds the layout mode for the items. When the mode is Batched,
        # // the items are laid out in batches of batchSize items, while processing events.
        # // This makes it possible to instantly view and interact with the visible items
        # // while the rest are being laid out.
        self.view().setLayoutMode(QListView.Batched)
        #  // batchSize : int
        # // This property holds the number of items laid out in each batch
        # // if layoutMode is set to Batched. The default value is 100."

        try:
            self.setInsertPolicy(self.NoInsert)
            self.setFocusPolicy(Qt.StrongFocus)
            self.setEditable(True)

            # add a filter model to filter matching items
            self.pFilterModel = QSortFilterProxyModel(self)
            self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
            self.pFilterModel.setSourceModel(self.model())

            # add a completer, which uses the filter model
            self.completer = QCompleter(self.pFilterModel, self)
            # always show all (filtered) completions
            self.completer.setCompletionMode(
                QCompleter.UnfilteredPopupCompletion)
            self.setCompleter(self.completer)

            # connect signals
            self.lineEdit().textEdited.connect(
                self.pFilterModel.setFilterFixedString)
            self.lineEdit().textEdited.connect(self.correctInput)

            # corrct qt bug:
            style = "QWidget{font-size: " + str(self.fontInfo().pointSize(
            )) + "pt;font-family: " + self.fontInfo().family() + ";}"
            self.completer.popup().setStyleSheet(style)
            # stat vars
            self.query = None
            self.layer = None
            self.doQueryOnShow = False
            self.masterExpression = None
            self.child = None

        except Exception as e:
            self.info.err(e)

    def hideEvent(self, e):
        self.isHidden.emit()

    def showEvent(self, e):
        try:
            if self.doQueryOnShow:
                self.buildList()
        except:
            pass

    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

    def setQuery(self, query):
        self.query = query
        self.tools = self.query.get('tools', [])
        self.doQueryOnShow = query.get('load', True)

    def Layer(self):
        return self.layer

    def setLayer(self, layer):
        self.layer = layer

    def Expression(self):
        return self.currentData()

    def Query(self):
        return self.query

    def setChild(self, cbo):
        try:
            self.child = cbo
        except Exception as e:
            self.info.err(e)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        try:
            if text is not None:
                index = self.findText(text, Qt.MatchContains)
                self.setCurrentIndex(index)
                if self.debug:
                    self.info.log(self.objectName(), "index:", index)
        except Exception as e:
            self.info.err(e)

    def correctInput(self, text=None):
        try:
            if self.debug: self.info.log("correctInput", text)
            if text is not None:
                index = self.findText(text, Qt.MatchContains)
                if self.debug:
                    self.info.log(self.objectName(), "index:", index)
                if index == -1:
                    self.setCurrentText(text[:-1])
                    self.on_completer_activated(text[:-1])
                index = self.findText(self.currentText(), Qt.MatchExactly)
                if index == -1:
                    self.resetFilter(False)
                else:
                    if index == self.currentIndex():
                        self.indexChanged(index)
                    else:
                        self.setCurrentIndex(index)
        except Exception as e:
            self.info.err(e)

    def resetFilter(self, resetSelf):
        try:
            if self.debug: self.info.log(self.objectName(), "reset")
            if resetSelf: self.setMasterExpression(None)
            if self.child: self.child.resetFilter(True)
        except Exception as e:
            self.info.err(e)

    def setMasterExpression(self, masterExpression):
        try:
            if self.debug:
                self.info.log(self.objectName(), "setMasterExpression",
                              self.masterExpression, "to", masterExpression)
            self.masterExpression = masterExpression
            if self.doQueryOnShow:
                self.buildList()
            else:
                if self.masterExpression is None:
                    self.clear()
                else:
                    self.buildList()
        except Exception as e:
            self.info.err(e)

    def buildList(self):
        if self.debug:
            self.info.log(self.objectName(), "buildList", self.query)

        self.setCurrentText('Lade...')
        self.setEnabled(False)
        self.repaint()
        if self.debug: self.info.log(self.objectName(), "excecuteQuery")
        try:
            self.currentIndexChanged.disconnect()
        except:
            pass
        try:
            self.clear()
            req = qgis.core.QgsFeatureRequest()
            req.setFlags(qgis.core.QgsFeatureRequest.NoGeometry)
            req.setSubsetOfAttributes(self.query['fields'],
                                      self.layer.fields())
            req.addOrderBy(self.query['fields'][0], True, True)
            if self.masterExpression is not None:
                req.setFilterExpression(self.masterExpression)
            values = []
            features = self.layer.getFeatures(req)
            for feat in features:
                displayStr = ''
                expr = ''
                for fn in self.query['fields']:
                    idx = self.layer.fields().indexFromName(fn)
                    if idx != -1:
                        value = feat[fn]
                        if isinstance(value, str):
                            value = "'" + value + "'"
                        if expr == '':
                            expr = expr + '"{0}"='.format(fn) + str(value)
                        else:
                            expr = expr + ' AND ' + '"{0}"='.format(fn) + str(
                                value)
                        displayStr = displayStr + str(feat[fn])
                    else:
                        displayStr = displayStr + str(fn)
                if not displayStr in values and displayStr.strip() != '':
                    values.append(displayStr)
                    self.addItem(displayStr, expr)
            if self.debug:
                self.info.log(self.objectName(), "items:", self.count())
            self.setCurrentIndex(-1)
            self.setSizeAdjustPolicy(self.AdjustToContents)
            self.setEnabled(True)
            self.completer.activated.connect(self.on_completer_activated)
            self.currentIndexChanged.connect(self.indexChanged)

            if self.masterExpression is not None:
                if self.count() == 1:
                    if self.debug:
                        self.info.log(self.objectName(),
                                      "self.setCurrentIndex(0)",
                                      "self.masterExpression",
                                      self.masterExpression)
                    self.setCurrentIndex(0)
            else:
                self.setCurrentIndex(-1)
        except Exception as e:
            self.info.err(e)

    def indexChanged(self, index):
        try:
            expr = self.currentData()
            if self.debug: self.info.log(self.objectName(), "cbo Expr:", expr)
            if self.masterExpression is not None:
                if expr is not None:
                    expr = self.masterExpression + ' AND ' + expr
                else:
                    expr = self.masterExpression
            self.info.log(self.objectName(), "Expr:", expr)
            if expr is not None:
                self.layer.selectByExpression(expr)
                self.gtomain.runcmd(self.tools)
            if self.child is not None:
                if self.debug: self.child.objectName()
                self.child.setMasterExpression(expr)
        except Exception as e:
            self.info.err(e)
Beispiel #20
0
class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(QtCore.Qt.StrongFocus)

        self.setEditable(True)

        # add a filter model to filter matching items

        self.pFilterModel = QtCore.QSortFilterProxyModel(self)

        self.pFilterModel.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)

        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model

        self.completer = QCompleter(self.pFilterModel, self)

        # always show all (filtered) completions

        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)

        self.setCompleter(self.completer)

        # connect signals

        self.lineEdit().textEdited[unicode].connect(
            self.pFilterModel.setFilterFixedString)

        self.completer.activated.connect(self.on_completer_activated)

    # on selection of an item from the completer, select the corresponding item from combobox

    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)

            self.setCurrentIndex(index)

    # 當lose focus時 判斷combobox輸入的text有沒有在item中
    def event(self, event):
        if event.type() == QtCore.QEvent.FocusOut:
            text = self.currentText()
            if text:
                index = self.findText(text)
                if index == -1:
                    self.setStyleSheet('QComboBox{border:1px solid red}')
                else:
                    self.setStyleSheet('QComboBox{border:1px solid gray}')

        return QComboBox.event(self, event)

    # on model change, update the models of the filter and completer as well

    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)

        self.pFilterModel.setSourceModel(model)

        self.completer.setModel(self.pFilterModel)

    # on model column change, update the model column of the filter and completer as well

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)

        self.pFilterModel.setFilterKeyColumn(column)

        super(ExtendedComboBox, self).setModelColumn(column)
Beispiel #21
0
class SecuritiesSelector(QComboBox):
    class SingletonStorage(metaclass=ThreadSafeSingleton):
        def __init__(self):
            self.__stock_list = []
            self.__lock = threading.Lock()
            self.__refresh_thread = None

        def get_stock_list(self) -> list:
            with self.__lock:
                return self.__stock_list.copy()

        def refresh_stock_list(self, sas_if: sasIF):
            with self.__lock:
                if self.__refresh_thread is None:
                    self.__refresh_thread = threading.Thread(
                        target=self.__update_stock_list,
                        name='SecuritiesSelectorRefresh',
                        args=(sas_if, ))
                    self.__refresh_thread.start()

        def __update_stock_list(self, sas_if: sasIF):
            stock_list = sas_if.sas_get_stock_info_list()
            with self.__lock:
                self.__stock_list = stock_list
                self.__refresh_thread = None

    def __init__(self, sas_if: sasIF, parent=None):
        super(SecuritiesSelector, self).__init__(parent)

        self.__sas_if: sasIF = sas_if

        self.__timer = QTimer()
        self.__timer.setInterval(1000)
        self.__timer.timeout.connect(self.on_timer)

        if self.__sas_if is not None:
            # Timer for update stock list
            self.__timer.start()

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)
        self.addItem('Loading...')

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(
            self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)

    # def keyPressEvent(self, event):
    #     super(SecuritiesSelector, self).keyPressEvent(event)
    #     key = event.key()
    #     if event.key() == QtCore.Qt.Key_Return:
    #         print('return key pressed')
    #     else:
    #         print('key pressed: %i' % key)

    def on_timer(self):
        # Check stock list ready and update combobox
        # if self.__data_utility is not None and \
        #         self.__data_utility.stock_cache_ready():
        #     stock_list = self.__data_utility.get_stock_list()

        stock_list = SecuritiesSelector.SingletonStorage().get_stock_list()
        if len(stock_list) > 0:
            self.clear()
            for stock_identity, stock_name in stock_list:
                self.addItem(stock_identity + ' | ' + stock_name,
                             stock_identity)
            self.__timer.stop()
        else:
            SecuritiesSelector.SingletonStorage().refresh_stock_list(
                self.__sas_if)

    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text: str):
        if self.__data_utility is None or \
                not self.__data_utility.stock_cache_ready():
            return
        if text is not None and text != '':
            self.__data_utility.guess_securities(text)
            index = self.findData(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))

    def setModel(self, model):
        super(QComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)

    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(QComboBox, self).setModelColumn(column)

    def select_security(self, security: str, linkage: bool):
        for index in range(self.count()):
            stock_identity = self.itemData(index)
            if stock_identity == security:
                self.setCurrentIndex(index)
                break

    def get_input_securities(self) -> str:
        # select_index = self.currentIndex()
        # if select_index >= 0:
        #     return self.itemData(select_index)
        # else:
        input_securities = self.currentText()
        if '|' in input_securities:
            input_securities = input_securities.split('|')[0].strip()
        return input_securities.strip()

    def get_select_securities(self) -> str:
        select_index = self.currentIndex()
        return self.itemData(select_index) if select_index >= 0 else ''
class DiscoveryPlugin:
    def __init__(self, _iface):
        # Save reference to the QGIS interface
        self.iface = _iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)

        # Variables to facilitate delayed queries and database connection management
        self.icon_loading = ':plugins/_Discovery_sqlite/icons/loading.gif'
        self.db_timer = QTimer()
        self.line_edit_timer = QTimer()
        self.line_edit_timer.setSingleShot(True)
        self.line_edit_timer.timeout.connect(self.reset_line_edit_after_move)
        self.next_query_time = None
        self.last_query_time = time.time()
        self.db_conn = None
        self.search_delay = 0.5  # s
        self.query_sql = ''
        self.query_text = ''
        self.query_dict = {}
        self.db_idle_time = 60.0  # s

        self.search_results = []
        self.tool_bar = None
        self.search_line_edit = None
        self.completer = None

        self.marker = QgsVertexMarker(iface.mapCanvas())
        self.marker.setIconSize(15)
        self.marker.setPenWidth(2)
        self.marker.setColor(QColor(226, 27, 28))  #51,160,44))
        self.marker.setZValue(11)
        self.marker.setVisible(False)
        self.marker2 = QgsVertexMarker(iface.mapCanvas())
        self.marker2.setIconSize(16)
        self.marker2.setPenWidth(4)
        self.marker2.setColor(QColor(255, 255, 255, 200))
        self.marker2.setZValue(10)
        self.marker2.setVisible(False)

    def initGui(self):

        # Create a new toolbar
        self.tool_bar = self.iface.addToolBar(u'Панель поиска')
        self.tool_bar.setObjectName('Discovery_sqlite_Plugin')

        # Add search edit box
        self.search_line_edit = QgsFilterLineEdit()
        self.search_line_edit.setSelectOnFocus(True)
        self.search_line_edit.setShowSearchIcon(True)
        self.search_line_edit.setPlaceholderText(
            u'Поиск адреса или участка...')
        # self.search_line_edit.setMaximumWidth(768)
        self.tool_bar.addWidget(self.search_line_edit)

        # loading indicator
        self.load_movie = QMovie()
        self.label_load = QLabel()
        self.tool_bar.addWidget(self.label_load)

        # Set up the completer
        model = QStandardItemModel()
        self.completer = QCompleter([])  # Initialise with en empty list
        self.completer.setCaseSensitivity(Qt.CaseInsensitive)
        self.completer.setMaxVisibleItems(30)
        self.completer.setModelSorting(
            QCompleter.UnsortedModel)  # Sorting done in PostGIS
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion
                                         )  # Show all fetched possibilities
        self.completer.setModel(model)
        tableView = QTableView()
        tableView.verticalHeader().setVisible(False)
        tableView.horizontalHeader().setVisible(False)
        tableView.setSelectionBehavior(QTableView.SelectRows)
        tableView.setShowGrid(False)
        # tableView.verticalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
        tableView.verticalHeader().setSectionResizeMode(QHeaderView.Fixed)
        fontsize = QFontMetrics(
            tableView.verticalHeader().font()).height() + 2  #font size
        tableView.verticalHeader().setDefaultSectionSize(
            fontsize)  #font size 15
        tableView.horizontalHeader().setSectionResizeMode(
            QHeaderView.ResizeToContents)
        tableView.horizontalHeader().setStretchLastSection(True)
        tableView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.completer.setCompletionColumn(0)
        self.completer.setPopup(tableView)

        self.completer.activated[QModelIndex].connect(self.on_result_selected)
        self.completer.highlighted[QModelIndex].connect(
            self.on_result_highlighted)
        self.search_line_edit.setCompleter(self.completer)

        # Connect any signals
        self.search_line_edit.textEdited.connect(self.on_search_text_changed)
        self.search_line_edit.returnPressed.connect(self.returnPressed)

        self.read_config()

        # Search results
        self.search_results = []

        # Set up a timer to periodically perform db queries as required
        self.db_timer.timeout.connect(self.schedule_search)

    def read_config(self):
        qstring = ''
        self.data = self.settings_path()
        try:
            for line in self.data[1:]:
                words = line.split(';')
                postgissearchcolumn = words[2].strip()
                postgistable = words[0].strip()
                geomcolumn = words[3].strip()
                layername = words[4].strip()
                isSelect = int(words[5].strip())

                connection = sqlite3.connect(os.path.join(self.dbfile.strip()))

                cur = connection.cursor()

                qstring = u'select {2} from {0} where length({1})>0 LIMIT 1'.format(
                    postgistable, postgissearchcolumn, geomcolumn)
                cur.execute(qstring)
                connection.close()
            self.make_enabled(True)  # assume the config is invalid first
        except Exception as E:
            print(E)
            self.make_enabled(False)

    # включить или выключить поисковую строку в зависимости от результата проверки настроек
    def make_enabled(self, enabled):
        self.search_line_edit.setEnabled(enabled)
        self.search_line_edit.setPlaceholderText(
            u"Поиск адреса или участка..."
            if enabled else u"Поиск отключен: проверьте конфигурацию")

    def settings_path(self):
        p = os.path.join(self.plugin_dir, 'layers.ini')
        f = codecs.open(p, 'r', encoding='cp1251')
        data = f.readlines()

        dbfileline = data[0]
        if dbfileline[:2] == u'\\\\':
            self.dbfile = dbfileline
        elif dbfileline[1] == u':':
            self.dbfile = dbfileline
        else:
            self.dbfile = os.path.join(self.plugin_dir, dbfileline)
        f.close()
        return data

    def unload(self):
        self.db_timer.stop()
        self.db_timer.timeout.disconnect(self.schedule_search)
        self.completer.highlighted[QModelIndex].disconnect(
            self.on_result_highlighted)
        self.completer.activated[QModelIndex].disconnect(
            self.on_result_selected)
        self.search_line_edit.textEdited.disconnect(
            self.on_search_text_changed)
        self.search_line_edit.returnPressed.disconnect(self.returnPressed)
        self.tool_bar.clear()  # Clear all actions
        self.iface.mainWindow().removeToolBar(self.tool_bar)

    def clear_suggestions(self):
        model = self.completer.model()
        model.clear()
        # model.setStringList([])

    def returnPressed(self):
        if self.completer.popup().isHidden():
            self.do_search(self.search_line_edit.text())

    # def setLoading(self, isLoading):
    #     if self.label_load is None:
    #         return
    #     if isLoading:
    #         load_movie = QMovie()
    #         load_movie.setFileName(self.icon_loading)
    #         self.label_load.setMovie(load_movie)
    #         load_movie.start()
    #     else:
    #         load_movie = QMovie()
    #         load_movie.stop()
    #         self.label_load.setMovie(load_movie)

    def schedule_search(self):

        if self.next_query_time is not None and self.next_query_time < time.time(
        ):
            self.next_query_time = None  # Prevent this query from being repeated
            self.last_query_time = time.time()
            self.do_search(self.search_line_edit.text())
            self.db_timer.stop()
            # self.setLoading(False)
            self.search_line_edit.setShowSpinner(False)
        else:
            # self.setLoading(True)
            self.search_line_edit.setShowSpinner(True)
            if time.time() > self.last_query_time + self.db_idle_time:
                self.db_conn = None

    # def on_search_text_changed(self, new_search_text):
    def on_search_text_changed(self, new_search_text):
        # self.setLoading(False)
        self.search_line_edit.setShowSpinner(False)
        if len(new_search_text) < 3:
            self.db_timer.stop()
            self.clear_suggestions()
            return
        self.db_timer.start(300)
        self.next_query_time = time.time() + self.search_delay

    def do_search(self, new_search_text):

        if len(new_search_text) < 3:
            self.clear_suggestions()
            return

        self.clear_suggestions()

        self.query_text = new_search_text

        self.search_results = []
        self.suggestions = []

        for index, line in enumerate(self.data[1:]):
            curline_layer = line
            words = curline_layer.split(';')
            searchcolumn = words[2].strip()  # поле со значением для поиска
            postgistable = words[0].strip()  # таблица
            geomcolumn = words[3].strip()  # поле с геометрией
            layername = words[4].strip(
            )  # имя слоя в легенде для соответствий и выделения
            isSelect = int(
                words[5].strip())  # выделять ли объект в слое layername
            descript = words[1].strip(
            )  # описание. Выводится в списке результатов

            query_text, query_dict = self.get_search_sql(
                new_search_text, searchcolumn, postgistable)

            query_sql = query_text
            query_dict = query_dict
            self.perform_search(query_sql, query_dict, descript, postgistable,
                                layername, isSelect, searchcolumn)

        # QStringList - просто одна строка в выводе
        # if len(self.suggestions) > 0:
        #     model = self.completer.model()
        #     model.setStringList(self.suggestions)
        #     print(model)
        #     self.completer.complete()

        if len(self.suggestions) > 0:
            # model = self.completer.model()
            model = QStandardItemModel()
            font = QFont()
            font.setItalic(True)
            font.setPointSize(7)
            # заполняем модель
            for i, line in enumerate(self.suggestions):
                #icon
                pixmap = QPixmap(':plugins/_Discovery_sqlite/icons/' +
                                 line[2] + '.png')
                pixmap = pixmap.scaledToHeight(10)
                pixmap = pixmap.scaledToWidth(10)
                # itemImage = QStandardItem()
                # itemImage.setData(pixmap, Qt.DecorationRole)
                # model.setItem(i, 0, itemImage)

                itemLayer = QStandardItem(u"{1}[{0}]".format(
                    line[1], u' ' * 50))
                itemLayer.setFont(font)
                itemValue = QStandardItem(line[0])
                itemValue.setData(pixmap, Qt.DecorationRole)
                model.setItem(i, 0, itemValue)
                model.setItem(i, 1, itemLayer)

            self.completer.setModel(model)
            self.completer.complete()

        else:
            model = self.completer.model()
            # self.suggestions.append(u"<Не найдено>")   # для QStringList
            # model.setStringList(self.suggestions)   # для QStringList
            model.setItem(
                0, 0, QStandardItem('<Не найдено>'))  # для QStandardItemModel
            self.completer.complete()

    def perform_search(self, query_sql, query_dict, descript, tablename,
                       layername, isSelect, searchcolumn):
        cur = self.get_db_cur()
        cur.execute(query_sql, query_dict)
        for row in cur.fetchall():
            geom, suggestion_text = row[0], row[1]
            self.search_results.append(geom)
            self.suggestions.append([
                suggestion_text, descript, tablename, layername, isSelect,
                searchcolumn
            ])
            # self.suggestions.append(suggestion_text)   # для QStringList

    def get_search_sql(self, search_text, search_column, table):

        wildcarded_search_string = ''
        for part in search_text.split():
            wildcarded_search_string += '%' + part  #.lower()
        wildcarded_search_string += '%'
        wildcarded_search_string = wildcarded_search_string
        query_dict = {'search_text': wildcarded_search_string}

        # wildcarded_search_string = wildcarded_search_string.encode('cp1251')
        query_text = u"SELECT WKT_GEOMETRY AS geom, {0} AS suggestion_string FROM {1} WHERE ({0}) LIKE '{2}' ORDER BY {0} LIMIT 1000".format(
            search_column, table, wildcarded_search_string)
        # query_text = query_text.decode('cp1251')
        return query_text, query_dict

    def on_result_selected(self, result_index):
        resultIndexRow = result_index.row()

        if len(self.search_results) < 1:
            self.search_line_edit.setPlaceholderText(u'')
            return
        # What to do when the user makes a selection
        geometry_text = self.search_results[resultIndexRow]
        location_geom = QgsGeometry.fromWkt(geometry_text)
        canvas = self.iface.mapCanvas()
        # dst_srid = canvas.mapRenderer().destinationCrs().authid()
        # Ensure the geometry from the DB is reprojected to the same SRID as the map canvas
        location_centroid = location_geom.centroid().asPoint()

        result_text = self.completer.completionModel().index(
            resultIndexRow, 0).data()

        if self.suggestions[resultIndexRow][2] in (
                u"adres_nd") and location_geom.type() == 0:  # point
            self.show_marker(location_centroid)
            self.iface.mapCanvas().setExtent(location_geom.boundingBox())
            self.iface.mapCanvas().zoomScale(1000)
            layer_build = self.find_layer(u"Здания")
            if layer_build != None:
                layer_build.selectByIds([])
                for feat in layer_build.getFeatures(
                        QgsFeatureRequest().setFilterRect(
                            QgsRectangle(self.iface.mapCanvas().extent()))):
                    if location_geom.intersects(feat.geometry()):
                        # self.show_marker_feature(feat.geometry())
                        self.iface.setActiveLayer(layer_build)
                        layer_build.selectByIds([feat.id()])
                        layer_build.triggerRepaint()
                        return

        else:  #not point
            layername = self.suggestions[resultIndexRow][3]
            isSelect = self.suggestions[resultIndexRow][4]
            searchcolumn = self.suggestions[resultIndexRow][5]

            box = location_geom.boundingBox()
            if box.height() > box.width():
                max = box.height()
            else:
                max = box.width()
            box.grow(max * 0.10)
            self.iface.mapCanvas().setExtent(box)

            if isSelect == 1:
                selLayer = self.find_layer(layername)
                if selLayer is not None:
                    for feat in selLayer.getFeatures(
                            QgsFeatureRequest().setFilterRect(box)):
                        # print(feat[searchcolumn], str(result_text).strip())
                        try:
                            if str(feat[searchcolumn]) == str(
                                    result_text).strip():
                                self.iface.setActiveLayer(selLayer)
                                selLayer.selectByIds([feat.id()])
                                selLayer.triggerRepaint()
                                break
                        except Exception as E:
                            print(E)
                            break

            self.show_marker_feature(location_geom)

        canvas.refresh()
        self.line_edit_timer.start(0)
        # self.db_timer.stop()

    def get_db_cur(self):
        # Create a new new connection if required
        if self.db_conn is None:
            self.db_conn = sqlite3.connect(os.path.join(self.dbfile.strip()))
        return self.db_conn.cursor()

    def on_result_highlighted(self, result_idx):
        self.line_edit_timer.start(0)

    def reset_line_edit_after_move(self):
        self.search_line_edit.setText(self.query_text)

    def find_layer(self, layer_name):
        for search_layer in self.iface.mapCanvas().layers():
            if search_layer.name() == layer_name:
                return search_layer
        return None

    def show_marker(self, point):
        for m in [self.marker, self.marker2]:
            m.setCenter(point)
            m.setOpacity(1.0)
            m.setVisible(True)
        QTimer.singleShot(4000, self.hide_marker)

    def hide_marker(self):
        opacity = self.marker.opacity()
        if opacity > 0.:
            # produce a fade out effect
            opacity -= 0.1
            self.marker.setOpacity(opacity)
            self.marker2.setOpacity(opacity)
            QTimer.singleShot(100, self.hide_marker)
        else:
            self.marker.setVisible(False)
            self.marker2.setVisible(False)

    def show_marker_feature(self, geom):
        if geom.type() == 2:  #poly
            self.r = QgsRubberBand(iface.mapCanvas(), True)
        elif geom.type() == 1:  #line
            self.r = QgsRubberBand(iface.mapCanvas(), False)
        self.r.setToGeometry(geom, None)
        self.r.setColor(QColor(255, 0, 0, 200))
        self.r.setFillColor(QColor(255, 0, 0, 50))
        self.r.setWidth(2)
        self.r.setZValue(9)

        QTimer.singleShot(4000, self.hide_marker_feature)

    def hide_marker_feature(self):
        opacity = self.r.opacity()
        if opacity > 0.:
            # produce a fade out effect
            opacity -= 0.1
            self.r.setOpacity(opacity)
            QTimer.singleShot(100, self.hide_marker_feature)
        else:
            iface.mapCanvas().scene().removeItem(self.r)