问题描述
MRE:
from PyQt5.QtCore import QRect,Qt,QAbstractTableModel
from PyQt5.QtWidgets import QApplication,QMainWindow,QTableView,QWidget,QVBoxLayout,QLineEdit,QListWidget
import sys,types
class MyTableModel( QAbstractTableModel ):
def __init__( self ):
super(MyTableModel,self).__init__()
data = [
[4,9,2],[1,0],[3,5,]
self._data = data
def data(self,index,role):
if role == Qt.displayRole:
return self._data[index.row()][index.column()]
def rowCount(self,index):
return len(self._data)
def columnCount(self,index):
return len(self._data[0])
class Ui_MainWindow(object):
def setupUi(self,MainWindow):
MainWindow.resize(600,700 )
self.centralwidget = QWidget(MainWindow)
self.verticalLayoutWidget = QWidget(self.centralwidget)
self.verticalLayoutWidget.setGeometry( QRect(20,20,500,500))
self.verticalLayout = QVBoxLayout(self.verticalLayoutWidget)
self.comps = []
self.title_line_edit = QLineEdit(self.verticalLayoutWidget)
self.comps.append( self.title_line_edit )
self.verticalLayout.addWidget(self.title_line_edit)
self.tags_list = QListWidget(self.verticalLayoutWidget)
self.comps.append( self.tags_list )
self.verticalLayout.addWidget(self.tags_list)
# UNCOMMENT THESE LInes:
# self.table_view = QTableView(self.verticalLayoutWidget)
# self.comps.append( self.table_view )
# self.table_view.setGeometry(QRect(20,200,200))
# self.verticalLayout.addWidget(self.table_view)
# self.table_view.setModel( MyTableModel() )
self.title_line_edit2 = QLineEdit(self.verticalLayoutWidget)
self.comps.append( self.title_line_edit2 )
self.verticalLayout.addWidget(self.title_line_edit2)
MainWindow.setCentralWidget(self.centralwidget)
class MyWindow(QMainWindow):
def __init__(self):
super(MyWindow,self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def focus_in_event( self,event ):
self.original_stylesheet = self.styleSheet()
self.setStyleSheet( 'border:1px solid rgb(0,255,0);' )
def focus_out_event( self,event ):
self.setStyleSheet( self.original_stylesheet )
for comp in self.ui.comps:
comp.focusInEvent = types.MethodType( focus_in_event,comp )
comp.focusOutEvent = types.MethodType( focus_out_event,comp )
app = QApplication(sys.argv)
application = MyWindow()
application.show()
sys.exit(app.exec())
按原样,焦点选项卡可以很好地浏览各个组件。
但是当您取消添加QTableView
的注释时,使用Tab键进入该组件意味着您无法再次使用Tab键。我尝试了Shift-Tab(在相反的循环方向上切换,但仍在表格单元格内),并尝试了Ctrl-Tab / Ctrl-Shift-Tab(似乎可以移动当前单元格)。
我根本不希望使用Tab键来浏览这些单元格(箭头导航键做同样的事情),只是希望这种“缠身”不会发生,所以我可以通过Tab / Shift-Tab键浏览所有组件像以前一样以循环方式。
我尝试了几件事,将这些行添加到MyWindow.__init__
的末尾:
# seemingly no effect:
def focus_next_prev_child( self,next ):
return False
self.ui.table_view.focusNextPrevChild = types.MethodType( focus_next_prev_child,comp )
# just omits the table view from the focus cycle:
self.ui.table_view.setFocusPolicy( Qt.NoFocus )
我还尝试拦截到达表视图的击键(再次将这些行添加到MyWindow.__init__
:
def keypress_event( self,key_event ):
modifs = key_event.modifiers()
key = key_event.key()
def unmodified_not_keypad():
print( f'unmodified,key: {hex( key )} text: {key_event.text()}' )
# strangely,if you press Shift-Tab,this gets to here (i.e. unmodified)
if key == Qt.Key_Tab or key == Qt.Key_Backtab:
# what might I do here?
# how might I find the next component in the cycle (forwards or backwards)?
return True
switcher = {
0x00000000: unmodified_not_keypad,}
def print_invalid():
print( f'invalid,hex( modifs): {hex(modifs)}' )
# if any called function returns True this means skip the default action...
if switcher.get( int( modifs ),print_invalid )():
return
# execute default action:
QTableView.keyPressEvent( self,key_event )
self.ui.table_view.keyPressEvent = types.MethodType( keypress_event,self.ui.table_view )
这确实拦截了Tab和Shift-Tab,并阻止了默认操作,但是我不知道如何在焦点循环中找到合适的组件。似乎也像是大锤子,要打破螺母:大概有一种更优雅的方式来获得我想要的行为...
解决方法
如果您根本不想在所有单元格之间切换,请添加using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
string EdgeVersion = string.Empty;
//open the registry and parse through the keys until you find Microsoft.MicrosoftEdge
RegistryKey reg = Registry.ClassesRoot.OpenSubKey(@"Local Settings\Software\Microsoft\Windows\CurrentVersion\AppModel\PackageRepository\Packages");
if (reg != null)
{
foreach (string subkey in reg.GetSubKeyNames())
{
if (subkey.StartsWith("Microsoft.MicrosoftEdge"))
{
//RegEx: (Microsoft.MicrosoftEdge_)(\d +\.\d +\.\d +\.\d +)(_neutral__8wekyb3d8bbwe])
Match rxEdgeVersion = null;
rxEdgeVersion = Regex.Match(subkey,@"(Microsoft.MicrosoftEdge_)(?<version>\d+\.\d+\.\d+\.\d+)(_neutral__8wekyb3d8bbwe)");
//just after that value,you need to use RegEx to find the version number of the value in the registry
if (rxEdgeVersion.Success)
EdgeVersion = rxEdgeVersion.Groups["version"].Value;
}
}
}
Console.WriteLine("Edge Version(empty means not found): {0}",EdgeVersion);
Console.ReadLine();
}
}
}
https://doc.qt.io/qt-5/qabstractitemview.html#tabKeyNavigation-prop