我使用PyQt创建GUI应用程序。在从QTableView继承的视图中,需要检测用户双击行时选择的行。该表有排序,但没有编辑。
我该怎么办?
注意 - 尝试了doubleClicked(int)信号。它是由鼠标按钮发出的,而不是由数据单元发出的,所以它从未被触发过。 :(
伊恩
答案 0 :(得分:16)
我不明白。 QTableView的doubleClicked信号具有签名
void doubleClicked ( const QModelIndex & index )
如果连接该信号,则应获得正确的QModelIndex。
答案 1 :(得分:5)
不再需要使用SIGNAL:
self.your_table.doubleClicked.connect(your_function)
“doubleClicked”继承自QAbstractItemView。
答案 2 :(得分:3)
一旦你有了modelIndex(来自上面的Frank评论),你就可以用它来找到双击了哪个单元格。
def slotDoubleClicked(self, mi):
row = mi.row()
column = mi.column()
然后,您可以使用这些行和列值来使用table.setItem(row,column,newdata)或其他表方法访问该表
答案 3 :(得分:1)
就像@regomodo所说,您可以通过以下方式将函数简单地连接到双击上:
public partial class Form1 : Form
{
// Program Settings and Controls
private readonly Panel pnlBacteria; // Panel representing a piece of bacteria
private readonly Random random = new Random(); // For randomly-generated values
private readonly Timer tmrMoveBacteria; // Timer used for bacteria movement
private readonly int bacteriaSize = 20; // Stores the size for our bacteria
private const int maxDistance = 50; // The maximum number of moves allowed in the same direction.
private const int stepDistance = 3; // The distance to travel on each iteration of the timer. Smaller number is slower and smoother
private readonly List<int> weightedDistances; // Contains a weighted list of distances (lower numbers appear more often than higher ones)
// Bacteria state variables
private Direction direction; // Stores the current direction bacteria is moving
private int distance; // Stores the distance remaining to travel in current direction
// Represents possible directions for bacteria to move
private enum Direction
{
North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest
}
public Form1()
{
InitializeComponent();
// Initialize our weighted differences array so that 1 is
// chosen most often and maxDistance is chosen the least often
weightedDistances = new List<int>();
for (var i = 0; i < maxDistance; i++)
{
var weight = maxDistance / (i + 1);
for (var j = 0; j <= weight; j++)
{
weightedDistances.Add(i + 1);
}
}
// Give life to the bacteria
pnlBacteria = new Panel
{
BackColor = Color.Red,
Width = bacteriaSize,
Height = bacteriaSize,
Left = random.Next(0, ClientRectangle.Width - bacteriaSize),
Top = random.Next(0, ClientRectangle.Height - bacteriaSize)
};
Controls.Add(pnlBacteria);
// Start bacteria movement timer
tmrMoveBacteria = new Timer {Interval = 10};
tmrMoveBacteria.Tick += TmrMoveBacteria_Tick;
tmrMoveBacteria.Start();
}
/// <summary>
/// Sets the direction and distance fields to valid values based on the
/// current bacteria position, direction, and remaining distance
/// </summary>
private void UpdateDirectionAndDistance()
{
// Get all directions
var validDirections = Enum.GetValues(typeof(Direction)).Cast<Direction>();
// Remove invalid directions (based on the bacteria position)
if (pnlBacteria.Top < bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("North"));
if (pnlBacteria.Right > ClientRectangle.Width - bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("East"));
if (pnlBacteria.Left < bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("West"));
if (pnlBacteria.Bottom > ClientRectangle.Height - bacteriaSize) validDirections =
validDirections.Where(dir => !dir.ToString().Contains("South"));
// If we're supposed to keep on moving in the same
// direction and it's valid, then we can exit
if (distance > 0 && validDirections.Contains(direction)) return;
// If we got here, then we're setting a new direction and distance
distance = weightedDistances[random.Next(weightedDistances.Count)];
var directions = validDirections.Where(d => d != direction).ToList();
direction = directions[random.Next(directions.Count)];
}
/// <summary>
/// Executes on each iteration of the timer, and moves the bacteria
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TmrMoveBacteria_Tick(object sender, EventArgs e)
{
// Ensure direction and distance are valid
UpdateDirectionAndDistance();
// Move the bacteria
var dirStr = direction.ToString();
if (dirStr.Contains("North")) pnlBacteria.Top -= stepDistance;
if (dirStr.Contains("East")) pnlBacteria.Left += stepDistance;
if (dirStr.Contains("South")) pnlBacteria.Top += stepDistance;
if (dirStr.Contains("West")) pnlBacteria.Left -= stepDistance;
distance--;
}
}
然后,如果您想知道用户双击了哪一行,可以使用以下代码:
self.your_table.doubleClicked.connect(your_function)
它将返回对应于行号或列号的整数。 双击将删除先前的选择,因此始终只有一个值。
如果将功能链接到按钮或其他信号,则会收到包含用户选择的多个元素的列表。
例如,您可以使用以下代码轻松检索所有选定行的列表:
for idx in self.your_table.selectionModel().selectedIndexes():
row_number = idx.row()
column_number = idx.column()
这将返回所有选定行的列表(set函数还将删除所有重复项)。
干杯!