Найти - Пользователи
Полная версия: PyQt4+Python3. Как отследить нажатие на клавишу или комбинацию клавиш?
Начало » GUI » PyQt4+Python3. Как отследить нажатие на клавишу или комбинацию клавиш?
1 2 3
Пытон
Возьмём QListWidget.
Нужно отследить нажатие на клавишу del и удалить текущий элемент списка.
А, допустим, комбинация ctrl+del должна очистить весь список.
И как это сделать? Что-то я ничего в интернете не могу найти или не могу понять то, что, всё-таки, нахожу.
Подскажите код или подскажите ссылку на пример кода.
Пытон
Какой сигнал обрабатывать?
Пытон
Видимо, вопрос катастрофически сложен или катастрофически некорректен…
dartNNN
Посмотри в сторону QAction, им можно задавать хоткей и делать чего хочешь.
Rodegast
Должно быть как то так:
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui

class ListWidget(QtGui.QListWidget):
def __init__(self,parent = None):
QtGui.QListWidget.__init__(self,parent)
self.ikl = None # Идентификатор клавиши

def event(self,e):
if e.type() == QtCore.QEvent.Shortcut and self.ikl == e.shortcutId():
print e.key()
return QtGui.QListWidget.event(self,e)

class Dialog(QtGui.QDialog):

def __init__(self):
QtGui.QDialog.__init__(self)
self.Tablic = ListWidget(self)
self.Tablic.ikl = self.Tablic.grabShortcut(QtGui.QKeySequence("Ctrl+del"))

if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
win = Dialog()
win.show()
sys.exit(app.exec_())
Ginibe
похожая ситуация

исходные:
ось - winXP SP3
питон - 2.7
PyQt - 4.7.1

обыскался в инете, смотрел доки - понял какие сигналы нужно ловить, а вот как …. ?

простецкий пример, немного подшаманил и закоментил для упрощения, рабочий
какой код нужно добавить и главное где, что бы функция/слот (в коде ее еще нет) возвращала елемент списка или номер строки или еще какую то инфу о выбранном элементе по клику мыши или нажатию клавы “Enter”
# -*- coding: utf-8 -*-

import sys
#import pyodbc
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def main():
app = QApplication(sys.argv)
w = WindowSlctnList()
w.show()
sys.exit(app.exec_())

class WindowSlctnList(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)

# создается списочек имен, типа строк
listName = getListNameTable()
#экземпляр класса абстрактной модели, типа список
lm = ModelSlctnList(listName, self)
#экземпляр класса представлений для просмотра списка
lv = QListView()
lv.setModel(lm)

#определяется виджет для представления модели
layout = QVBoxLayout()
layout.addWidget(lv)
self.setLayout(layout)

#задействуются синалы от виджета
#клик на мыши - clicked
#энтер на клаве - activated

class ModelSlctnList(QAbstractListModel):
def __init__(self, datain, parent=None, *args):
QAbstractListModel.__init__(self, parent, *args)
self.listdata = datain

def rowCount(self, parent=QModelIndex()):
return len(self.listdata)

def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.listdata[index.row()])
else:
return QVariant()

def getListNameTable():
# #коннектимся с базой
# db = pyodbc.connect('DSN=db_vek')
# #обзаводимся указателем на объекты базы
# cursor = db.cursor()
# #пройдемся по таблицам базы
# tablesName = [table.table_name.decode('cp1251') for table in cursor.tables() if table.table_name[:4] != "MSys" and table.table_name[:4] != "~TMP"]
# db.close()
# return tablesName
#пример с готовой таблой
return ['table_name_0','table_name_1','table_name_2','table_name_3','table_name_4','table_name_5','table_name_6','table_name_7','table_name_8','table_name_9']

if __name__ == "__main__":
main()
dartNNN
Rodegast
Должно быть как то так:
Достаточно сложно на мой взгляд. Как я написал, пользую QAction. Нет необходтмости перелпределять QListWidget. Вот пример
        self.quitAct = QtGui.QAction(self.tr("&Quit"), self)
self.quitAct.setShortcut(self.tr("Ctrl+Q"))
self.quitAct.setStatusTip(self.tr("Quit the application"))
self.quitAct.triggered.connect(self.close)
Для MainWindow
        self.fileMenu = self.menuBar().addMenu(self.tr("&File"))
self.fileMenu.addAction(self.quitAct)
Для Widget
        self.addAction(self.quitAct)
И уже в методе подключенном к этому Action (self.close в примере) делать все необходимые манипуляции.
В случае клика мышки по ListView, то учитывая, что он наследуется от QAbstractItemView, видим у него сигнал void clicked (const QModelIndex&). Ход мыслей понятен?
Ginibe
dartNNN, спасибо за подсказку, сработало.
нашел пост с подобным вопросом… утверждается что данные “кликнутого” элемента можна достать с помощь использования класса QItemSelectionModel
пробовал…
правда даошло не спервого раза :D

при чем синал, судя по выдаваемым результатам, от QItemSelectionModel срабатывает до синала “клик” от QListView
приведу код для тех кто будет искать ответы “после меня”:
# -*- coding: utf-8 -*-
from select import select

import sys
import pyodbc
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def main():
app = QApplication(sys.argv)
w = WindowSlctnList()
w.show()
sys.exit(app.exec_())

class WindowSlctnList(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)

# создается списочек имен, типа строк
listName = getListNameTable()
#экземпляр класса абстрактной модели, типа список
self.lm = ModelSlctnList(listName, self)
#экземпляр класса представлений для просмотра списка
self.lv = QListView()
self.lv.setModel(self.lm)
#задействуются синалы от виджета
#клик на мыши - clicked
self.lv.clicked.connect(self.selectName)

#для определения выбора строки курсором используется сласс ВЫДЕЛЕННЫХ ЭЛЕМЕНТОВ
#экземпляр класса QItemSelectionModel - класс выделенных/маркированных элементов для получения инфы об этих элементах
self.lms = QItemSelectionModel(self.lm)
#указываем представлению имя экземпляра класса ВЫДЕЛЕННЫХ ЭЛЕМЕНТОВ
self.lv.setSelectionModel(self.lms)
#описываем сигнал, указывающий об изменениях в выделенных/маркированных элементах
self.lms.selectionChanged.connect(self.chSelection)

#определяется виджет для представления модели
layout = QVBoxLayout()
layout.addWidget(self.lv)
self.setLayout(layout)

def selectName(self):
strOut = u'нажалось в selectName'
select = self.lms.currentIndex()
rowSel = select.row()
print strOut, rowSel
return

def chSelection(self):
strOut = u"нажалось в chSelection"
select = self.lms.currentIndex()
rowSel = select.row()
print strOut, rowSel
return

class ModelSlctnList(QAbstractListModel):
def __init__(self, datain, parent=None, *args):
QAbstractListModel.__init__(self, parent, *args)
self.listdata = datain

def rowCount(self, parent=QModelIndex()):
return len(self.listdata)

def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.listdata[index.row()])
else:
return QVariant()

def getListNameTable():
# #коннектимся с базой
# db = pyodbc.connect('DSN=db_vek')
# #обзаводимся указателем на объекты базы
# cursor = db.cursor()
# #пройдемся по таблицам базы
# tablesName = [table.table_name.decode('cp1251') for table in cursor.tables() if table.table_name[:4] != "MSys" and table.table_name[:4] != "~TMP"]
# db.close()
# return tablesName
# #пример с готовой таблой
return ['table_name_0','table_name_1','table_name_2','table_name_3','table_name_4','table_name_5','table_name_6','table_name_7','table_name_8','table_name_9']

if __name__ == "__main__":
main()
Rodegast
> Достаточно сложно на мой взгляд.

Ну это был немного переделанный пример из книги Прохоренок-а ;) В принципе QListWidget можно не переопределять, а сразу ловить событие через event.
dartNNN
Ginibe
данные “кликнутого” элемента можна достать с помощь использования класса QItemSelectionModel
Вообще-то я имел ввиду что-то такое:
import sip
sip.setapi('QVariant', 1)
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def main():
app = QApplication(sys.argv)
w = WindowSlctnList()
w.show()
sys.exit(app.exec_())

class WindowSlctnList(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)

# создается списочек имен, типа строк
listName = getListNameTable()
#экземпляр класса абстрактной модели, типа список
self.lm = ModelSlctnList(listName, self)
#экземпляр класса представлений для просмотра списка
self.lv = QListView()
self.lv.setModel(self.lm)
#задействуются синалы от виджета
#клик на мыши - clicked
self.lv.clicked.connect(self.selectName)

#определяется виджет для представления модели
layout = QVBoxLayout()
layout.addWidget(self.lv)
self.setLayout(layout)

def selectName(self, index):
print("row = {0}\ndata = {1}".format(index.row(), index.data().toString()))


class ModelSlctnList(QAbstractListModel):
def __init__(self, datain, parent=None, *args):
QAbstractListModel.__init__(self, parent, *args)
self.listdata = datain

def rowCount(self, parent=QModelIndex()):
return len(self.listdata)

def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.listdata[index.row()])
else:
return QVariant()



def getListNameTable():
return ['table_name_0','table_name_1','table_name_2','table_name_3','table_name_4','table_name_5','table_name_6','table_name_7','table_name_8','table_name_9']

if __name__ == "__main__":
main()
Все изменения в методе selectName.
+ не используется QItemSelectionModel
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB