简体   繁体   中英

How to Change the Focus from QListWidget to QLineEdit, If I press only any Alphabets (A-Z, a-z) or numbers(0 - 9)?

Face a problem to change the focus from QListWidget to QLineEdit .

If we press down_arrow or up_arrow from QLineEdit, focus changed from QLineEdit to Qlistwidget and press left_arrow or back_space from QListWidget, focus change from QListwidget to QLineEdit.

Suppose Focus in QListWidget , Now I press Any alphabets or numbers ( A -z or a -z or 0 - 9), How to change the focus from QListwidget to QLineEdit and appear that pressed key value in QLineEdit Box. (For example, If I press "H" from QListWidget, focus change from QListWidget to QLineEdit and the Character "H" appears in last(n th) postition)

import sys
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

item = ["Python", "Python 2.7", "Python 2.9", "Python 3.5", "Python 3.7", "National", "Zebra",
        "Apple", "X Ray", "Boat", "Tiger", "Item001", "Item002", "Item003", "Item004", "Item005",
        "001Item", "002Item", "003Item", "004Item", "005Item", "Ball", "Cat", "Dog", "Fish",
        "Gold Fish", "Star Fish", "2821", "2822", "2823", "2811", "2812", "2813"]
flag = 2


class Event_Handler(QWidget):
    def __init__(self):
        super().__init__()

        self.setMinimumSize(350, 600)
        self.textbox = QLineEdit()
        self.textbox.installEventFilter(self)
        self.textbox.textChanged.connect(self.func_textbox_textchanged)

        self.listbox_dummy = QListWidget()
        self.listbox_dummy.addItems(item)

        self.listbox = QListWidget()
        self.listbox.installEventFilter(self)
        self.listbox.addItems(item)

        self.label_1 = QLabel("Item Starts With (Alt+S)")
        self.label_2 = QLabel("Item Contains    (Alt+C)")
        self.label_3 = QLabel("Item Ends With   (Alt+E)")

        vbox1 = QVBoxLayout()
        vbox1.addWidget(self.textbox)
        vbox1.addWidget(self.listbox)
        vbox1.addWidget(self.label_1)
        vbox1.addWidget(self.label_2)
        vbox1.addWidget(self.label_3)
        self.setLayout(vbox1)

    def func_textbox_textchanged(self):
        global search_text, search_text_lenth, total_listbox_items, startitem_rowno, enditem_rowno, \
            startitem_count, containitem_count, enditem_count, item_normal, item_startswith, item_contains, \
            item_endswith, flag

        search_text = self.textbox.text()
        search_text_length = len(search_text)

        item_normal = self.listbox_dummy.findItems("*", Qt.MatchWildcard)
        item_startswith = self.listbox_dummy.findItems(search_text, Qt.MatchStartsWith)
        item_contains = self.listbox_dummy.findItems(search_text, Qt.MatchContains)
        item_endswith = self.listbox_dummy.findItems(search_text, Qt.MatchEndsWith)

        k = 0
        dummy_list = []
        for i in item_contains:
            if ((i.text().lower())[0:search_text_length]) == (search_text.lower()):
                dummy_list.append(k)
                startitem_rowno = (dummy_list[0])
                enditem_rowno = (dummy_list[-1])
            k = k + 1

        startitem_count = len(item_startswith)
        containitem_count = len(item_contains)
        enditem_count = len(item_endswith)

        if search_text_length == 1:
            flag = 1

        self.listbox.clear()

        if flag == 1:
            self.func_item_startswith()
        elif flag == 2:
            self.func_item_contains()
        elif flag == 3:
            self.func_item_endswith()
        elif flag == 0:
            self.func_item_contains()
        else:
            self.func_item_normal()

        if startitem_count == 0:
            flag = 2
            self.func_item_contains()

    def func_item_startswith(self):
        global flag
        flag = 1
        self.listbox.clear()

        if startitem_count > 0:
            for item in item_startswith:
                self.listbox.addItem(item.text())
        else:
            print("No Matching from start item")

    def func_item_contains(self):
        global flag
        flag = 2
        self.listbox.clear()

        if containitem_count > 0:
            for item in item_contains:
                self.listbox.addItem(item.text())
        else:
            print("No Matching from contains item")

    def func_item_endswith(self):
        global flag
        flag = 3
        self.listbox.clear()

        if enditem_count > 0:
            for item in item_endswith:
                self.listbox.addItem(item.text())
        else:
            print("No Matching from end item")

    def func_item_normal(self, normal_count=None):
        global falg
        flag = 0
        self.listbox.clear()

        if normal_count > 0:
            for item in item_normal:
                self.listbox.addItem(item.text())

    def eventFilter(self, source, event):
        global startitem_rowno, enditem_rowno

        if event.type() == QEvent.KeyPress and source is self.textbox:

            if event.modifiers() == Qt.AltModifier and event.key() == Qt.Key_S:
                self.func_item_startswith()
                return True
            if event.key() == Qt.Key_C and event.modifiers() == Qt.AltModifier:
                self.func_item_contains()
                return True
            if event.key() == Qt.Key_E and event.modifiers() == Qt.AltModifier:
                self.func_item_endswith()
                return True
            if event.key() == Qt.Key_Down:
                startitem_rowno = 0
                if flag != 2:
                    startitem_rowno = 0

                self.listbox.setFocus()
                self.listbox.setCurrentRow(startitem_rowno)

            if event.key() == Qt.Key_Up:
                enditem_rowno = len(self.listbox) - 1
                if flag != 2:
                    enditem_rowno = len(self.listbox) - 1
                self.listbox.setFocus()
                self.listbox.setCurrentRow(enditem_rowno)

            if event.key() == Qt.Key_Return:
                if len(self.listbox) == 1:
                    self.listbox.setCurrentRow(0)
                    self.textbox.setText(self.listbox.currentItem().text())
                    prin = self.listbox.currentItem().text()

        if event.type() == QKeyEvent.KeyPress and source is self.listbox:

            if event.key() == Qt.Key_Left or event.key() == Qt.Key_Backspace:
                self.textbox.setFocus()

            if event.key() == Qt.Key_Return:
                self.textbox.setText(self.listbox.currentItem().text())
                self.textbox.setFocus()


        return super(Event_Handler, self).eventFilter(source, event)

if __name__ == '__main__':
    myapp = QApplication(sys.argv)
    mywin = Event_Handler()
    mywin.show()
    sys.exit(myapp.exec_())

With my Python and Pyqt5 Knowledge, I got some solution , But I am sure, its not a Pythonic way . So Experts will guide me to get a correct pythonic approach .

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

flag = 1
search_text_length = 0
startitem_rowno = None
enditem_rowno = None

item = ["Python", "Python 2.7", "Python 2.9", "Python 3.5", "Python 3.7", "National", "Zebra",
        "Apple", "X Ray", "Boat", "Tiger", "Item001", "Item002", "Item003", "Item004", "Item005",
        "001Item", "002Item", "003Item", "004Item", "005Item", "Ball", "Cat", "Dog", "Fish",
        "Gold Fish", "Star Fish", "2821", "2822", "2823", "2811", "2812", "2813"]


class TitleValidator(QValidator):
    def validate(self, text, pos):
        return QValidator.Acceptable, text.title(), pos


class Listbox_008(QWidget):

    def __init__(self):
        super().__init__()
        self.setWindowTitle("List Box Example")
        self.func_mydesign()
        self.func_layout()
        self.func_load_data()

    # ----------------------------------------------------------------------------------
    def func_mydesign(self):

        self.textbox_search = QLineEdit()
        self.listbox_search = QListWidget()
        self.listbox_dummy = QListWidget()
        self.label_listbox_head = QLabel(" Available Items :")
        self.label_listbox_head.setAlignment(Qt.AlignCenter)
        self.label_noraml = QLabel("Available Items (Alt+A) :")
        self.label_starts = QLabel("Items &Starts With (Alt+S) : ")
        self.label_contains = QLabel("Items &Contains anywhere (Alt+C) : ")
        self.label_ends = QLabel("Items &Ends With (Alt+E) : ")
        self.label_noraml_count = QLabel("600")
        self.label_starts_count = QLabel()
        self.label_contains_count = QLabel()
        self.label_ends_count = QLabel()
        self.label_selected_item = QLabel("Selected Item")

        self.label_listbox_head.setFont(QFont("Caliber", 10, QFont.Bold))
        self.label_listbox_head.setAlignment(Qt.AlignCenter)
        self.label_listbox_head.setStyleSheet("background-color:blue;border-radius:4px;padding:2px;color:white")

        self.textbox_search.setFont(QFont("Caliber", 12, QFont.Bold))
        self.textbox_search.setFixedHeight(50)
        self.textbox_search.installEventFilter(self)
        self.textbox_search.textChanged.connect(self.func_textbox_textchanged)
        self.textbox_search.setStyleSheet(self.func_foucs_stylesheet_001())
        validator = TitleValidator(self.textbox_search)
        self.textbox_search.setValidator(validator)

        self.listbox_search.installEventFilter(self)
        self.listbox_search.setStyleSheet(self.func_foucs_stylesheet_001())
        self.listbox_search.itemClicked.connect(self.listbox_clicked)
        self.listbox_search.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.listbox_search.setFont(QFont("Arial", 10, QFont.Bold))

        self.label_noraml.setStyleSheet(self.func_qlabel_stylesheet_001())
        self.label_starts.setStyleSheet(self.func_qlabel_stylesheet_001())
        self.label_contains.setStyleSheet(self.func_qlabel_stylesheet_001())
        self.label_ends.setStyleSheet(self.func_qlabel_stylesheet_001())

        self.label_noraml_count.setStyleSheet(self.func_qlabel_stylesheet_002())
        self.label_starts_count.setStyleSheet(self.func_qlabel_stylesheet_002())
        self.label_contains_count.setStyleSheet(self.func_qlabel_stylesheet_002())
        self.label_ends_count.setStyleSheet(self.func_qlabel_stylesheet_002())

        self.label_selected_item.setFont(QFont("Caliber", 8, QFont.Bold))

    def func_layout(self):
        layout_top = QVBoxLayout()
        layout_top_1 = QHBoxLayout()
        layout_top_2 = QHBoxLayout()
        layout_top_3 = QVBoxLayout()
        layout_top_1.addWidget(self.textbox_search)
        layout_top_3.addWidget(self.label_listbox_head)
        layout_top_2.addWidget(self.listbox_search)
        layout_top.addLayout(layout_top_1)
        layout_top.addLayout(layout_top_3)
        layout_top.addLayout(layout_top_2)

        layout_bot = QVBoxLayout()

        layout_bot_1 = QFormLayout()
        layout_bot_1.setVerticalSpacing(5)
        layout_bot_1.setHorizontalSpacing(3)
        layout_bot_1.addRow(self.label_noraml, self.label_noraml_count)
        layout_bot_1.addRow(self.label_starts, self.label_starts_count)
        layout_bot_1.addRow(self.label_contains, self.label_contains_count)
        layout_bot_1.addRow(self.label_ends, self.label_ends_count)

        layout_bot_2 = QHBoxLayout()
        layout_bot_2.addStretch()
        layout_bot_2.addWidget(self.label_selected_item)
        layout_bot_2.addStretch()

        layout_bot.addLayout(layout_bot_1)
        layout_bot.addSpacing(10)
        layout_bot.addLayout(layout_bot_2)

        frame_top = QFrame()
        frame_top.setObjectName("frame_top")
        frame_top.setLayout(layout_top)

        frame_bot = QFrame()
        frame_bot.setObjectName("frame_bot")
        frame_bot.setLayout(layout_bot)

        layout_tot = QVBoxLayout()
        layout_tot.addWidget(frame_top)
        layout_tot.addWidget(frame_bot)

        frame_tot = QFrame()
        frame_tot.setObjectName("frame_tot")
        # frame_tot.setFixedSize(500,700)

        frame_tot.setStyleSheet(self.func_Qframe_stylesheet_001())
        frame_tot.setLayout(layout_tot)
        frame_tot.setFrameShape(QFrame.Box)
        frame_tot.setFrameShadow(QFrame.Plain)

        layout_main = QHBoxLayout()
        layout_main.addWidget(frame_tot)
        self.setLayout(layout_main)

    def func_load_data(self):
        global flag,startitem_rowno,enditem_rowno
        self.listbox_dummy.addItems(item)
        self.listbox_search.addItems(item)
        self.label_noraml_count.setText("{}".format(len(self.listbox_search)))
        startitem_rowno = 0
        enditem_rowno = len(self.listbox_search)-1


    def func_qlabel_stylesheet_001(self):
        return """
               QLabel{
               font-family: Caliber; font-style: bold; font-size:10pt; font-weight:normal;
               color:black; background-color:'Orange'; min-width:280px; qproperty-alignment:'AlignRight';

               }
               """

    def func_qlabel_stylesheet_002(self):
        return """
               QLabel{
               font-family: Caliber; font-style: bold; font-size:10pt; font-weight:normal;
               color:black; background-color:'Orange';min-width:100px; qproperty-alignment:'AlignLeft';
               }
               """

    def func_Qframe_stylesheet_001(self):
        return """
             QFrame#frame_bot {background-color:"orange"}
             QFrame#frame_top {background-color:#fff}
             QFrame#frame_tot {background-color:"light green"}
        """

    def func_foucs_stylesheet_001(self):
        return """
             QLineEdit:focus {border:4px solid red; ;}
             QListWidget:focus {border:20px solid red; border-style:;}
            """

    def eventFilter(self, source, event):
        global cursor_position,textbox_value

        if event.type() == QEvent.KeyPress and source is self.textbox_search:

            if event.modifiers() == Qt.AltModifier and event.key() == Qt.Key_S:
                flag = 1
                self.func_item_startswith()
                return True
            if event.key() == Qt.Key_C and event.modifiers() == Qt.AltModifier:
                flag = 2
                self.func_item_contains()
                return True
            if event.key() == Qt.Key_E and event.modifiers() == Qt.AltModifier:
                flag = 3
                self.func_item_endswith()
                return True

            if event.key() == Qt.Key_Down:
                self.listbox_search.setFocus()
                self.listbox_search.setCurrentRow(startitem_rowno)
                cursor_position = self.textbox_search.cursorPosition()
                textbox_value = self.textbox_search.text()


            if event.key() == Qt.Key_Up:
                self.listbox_search.setCurrentRow(enditem_rowno)
                self.listbox_search.setFocus()
                cursor_position = self.textbox_search.cursorPosition()
                textbox_value = self.textbox_search.text()


            if event.key() == Qt.Key_Return:
                if len(self.listbox_search) == 1:
                    self.listbox_search.setCurrentRow(0)
                    self.textbox_search.setText(self.listbox_search.currentItem().text())
                    prin = self.listbox_search.currentItem().text()
                    self.label_selected_item.setText("Selected Item : " + prin)
                    self.label_selected_item.adjustSize()
                else:
                    self.label_selected_item.setText("Select One Item........")
                    self.label_selected_item.adjustSize()

        if event.type() == QKeyEvent.KeyPress and source is self.listbox_search:


            if event.key() == Qt.Key_Left or event.key() == Qt.Key_Backspace:
                self.listbox_search.clearFocus()
                self.textbox_search.setFocus()
            elif event.key() == Qt.Key_Return:
                prin = self.listbox_search.currentItem().text()
                self.textbox_search.setText(self.listbox_search.currentItem().text())
                self.label_selected_item.setText("Selected Item : " + prin)
                self.label_selected_item.adjustSize()
                self.textbox_search.setFocus()
            else:
                self.textbox_search.setFocus()
                keyvalue = event.text()
                self.textbox_search.setText(textbox_value+keyvalue)
                self.textbox_search.setCursorPosition(cursor_position+1)

        return super(Listbox_008, self).eventFilter(source, event)

    def func_item_startswith(self):
        global flag,startitem_rowno,enditem_rowno
        flag = 1
        startitem_rowno = 0
        enditem_rowno = startitem_count - 1

        self.listbox_search.clear()
        self.label_listbox_head.setText("Item Start With")

        if startitem_count > 0:
            for item in item_startswith:
                self.listbox_search.addItem(item.text())
        else:
            print("No Matching from start item")

    def func_item_contains(self):
        global flag,startitem_rowno,enditem_rowno
        flag = 2
        self.listbox_search.clear()
        self.label_listbox_head.setText("Item Contains With")

        if containitem_count > 0:
            for item in item_contains:
                self.listbox_search.addItem(item.text())
        else:
            print("No Matching from contains item")


        dummy_list = []
        k = 0
        for i in item_contains:
            if i.text().lower()[0:search_text_length] == search_text.lower():
                dummy_list.append(k)
                startitem_rowno = dummy_list[0]
                enditem_rowno   = dummy_list[-1]
            k +=1
            if len(dummy_list) == 0 :
                startitem_rowno = 0
                enditem_rowno =  containitem_count-1


    def func_item_endswith(self):
        global flag, startitem_rowno, enditem_rowno
        flag = 3
        startitem_rowno = 0
        enditem_rowno = enditem_count - 1

        self.listbox_search.clear()
        self.label_listbox_head.setText("Item Ends With")

        if enditem_count > 0:
            for item in item_endswith:
                self.listbox_search.addItem(item.text())
        else:
            print("No Matching from end item")

    def func_item_normal(self):

        global falg,startitem_rowno,enditem_rowno
        flag = 0
        startitem_rowno = 0
        enditem_rowno = normal_count - 1

        self.listbox_search.clear()
        self.label_listbox_head.setText("Available Items")

        if normal_count > 0:
            for item in item_normal:
                self.listbox_search.addItem(item.text())

    def func_textbox_textchanged(self, txt):
        global search_text, search_text_length, total_listbox_item, availableitem_count, normal_count, startitem_count, \
            containitem_count, enditem_count, item_normal, item_startswith, item_contains, item_endswith, flag,\
            startitem_rowno, enditem_rowno

        search_text = self.textbox_search.text()
        search_text_length = len(search_text)
        total_listbox_item = len(self.listbox_search)

        item_normal = self.listbox_dummy.findItems("*", Qt.MatchWildcard)
        item_startswith = self.listbox_dummy.findItems(search_text, Qt.MatchStartsWith)
        item_contains = self.listbox_dummy.findItems(search_text, Qt.MatchContains)
        item_endswith = self.listbox_dummy.findItems(search_text, Qt.MatchEndsWith)

        normal_count = len(item_normal)
        startitem_count = len(item_startswith)
        containitem_count = len(item_contains)
        enditem_count = len(item_endswith)

        self.func_item_normal()


        self.label_noraml_count.setText("{}".format(normal_count))
        if search_text_length >= 1:
            self.label_starts_count.setText("{}".format(startitem_count))
            self.label_contains_count.setText("{}".format(containitem_count))
            self.label_ends_count.setText("{}".format(enditem_count))
        else:
            flag = 1
            self.label_starts_count.clear()
            self.label_contains_count.clear()
            self.label_ends_count.clear()

        self.listbox_search.clear()

        if flag == 1:
            self.func_item_startswith()
        elif flag == 2:
            self.func_item_contains()
        elif flag == 3:
             self.func_item_endswith()
        elif flag == 0:
            self.func_item_contains()
        else:
            self.func_item_normal()

        if search_text_length == 0:
            self.label_listbox_head.setText("Available Items :")
            self.label_listbox_head.adjustSize()

        if startitem_count == 0:
            flag = 2
            self.func_item_contains()


    def listbox_clicked(self, item):
        self.textbox_search.setText(item.text())
        self.textbox_search.setFocus()
    # -----------------------------------------------------------------------------------


def main():
    myapp = QApplication(sys.argv)
    mywindow = Listbox_008()
    width = mywindow.frameGeometry().width()
    height = mywindow.frameGeometry().height()
    # print("screensize",width)
    # print("screensize",height)
    # screenShape = QDesktopWidget().screenGeometry()
    # mywindow.resize(screenShape.width(), screenShape.height())
    # print("resolution",screenShape.width())
    # print("resolution",screenShape.height())

    mywindow.show()
    sys.exit(myapp.exec_())


if __name__ == "__main__":
    main()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM